void *os2ldcalloc(size_t num_elem, size_t size_elem) { APIRET rc; int ret; if (FirstTime) { if ((rc=DosAllocMem(&os2ldBase,RESERVED_BLOCKS * 4096, PAG_READ | PAG_WRITE | PAG_EXECUTE)) != 0) { xf86Msg(X_ERROR, "OS2LD: DosAllocMem failed, rc=%d\n", rc); return NULL; } /* Now commit the first 128Kb, the rest will * be done dynamically */ if ((rc=DosSetMem(os2ldBase, 32*4096, PAG_DEFAULT | PAG_COMMIT)) != 0) { xf86Msg(X_ERROR, "OS2LD: DosSetMem failed, rc=%d\n",rc); DosFreeMem(os2ldBase); return NULL; } os2ldCommitedTop = os2ldBase + 32*4096; os2ldTotalCommitedBlocks = 32; #ifdef DEBUG xf86Msg(X_INFO, "OS2LD: Initial heap at addr=%p\n", os2ldBase); #endif if ((os2ldHeap=_ucreate(os2ldBase, 32*4096, _BLOCK_CLEAN, _HEAP_REGULAR, os2ldAddToHeap, os2ldRemoveFromHeap)) == NULL) { xf86Msg(X_ERROR, "OS2LD: heap creation failed\n"); DosFreeMem(os2ldBase); return NULL; } if ((ret=_uopen(os2ldHeap)) != 0) { xf86Msg(X_ERROR, "OS2LD: heap open failed\n"); ret = _udestroy(os2ldHeap,_FORCE); DosFreeMem(os2ldBase); return(NULL); } FirstTime = FALSE; #ifdef DEBUG xf86Msg(X_INFO,"OS2LD: Created module heap at addr=%p\n", os2ldHeap); #endif } return _ucalloc(os2ldHeap,num_elem,size_elem); }
BOOL MemHeapInit(VOID) { PVOID pheap; if ( DosAllocMem(&pbasemem, CB_HEAPTOTAL, PAG_READ | PAG_WRITE) || DosSubSetMem(pbasemem, DOSSUB_INIT | DOSSUB_SPARSE_OBJ, CB_HEAPTOTAL) || DosSubAllocMem(pbasemem, &pheap, CB_HEAPBLOCK - CB_SUBSETOVHD) || (NULL == (hp = _ucreate(pheap, CB_HEAPBLOCK - CB_SUBSETOVHD, !_BLOCK_CLEAN, _HEAP_REGULAR, heapIncrease, heapDecrease))) || _uopen(hp) ) return FALSE; #ifdef DEBUGMEM openLogFile(); #endif return TRUE; }
/** * Initializes the shared structures. */ static void shared_init() { APIRET arc; int rc; arc = DosExitList(EXLST_ADD, ProcessExit); ASSERT_MSG(arc == NO_ERROR, "%ld", arc); #if defined(TRACE_ENABLED) && !defined(TRACE_USE_LIBC_LOG) /* * Allocate a larger buffer to fit lengthy TRACE messages and disable * auto-flush on EOL (to avoid breaking lines by stdout operations * from other threads/processes). */ setvbuf(stdout, NULL, _IOFBF, 0x10000); #endif while (1) { /* First, try to open the mutex */ arc = DosOpenMutexSem(MUTEX_LIBCX, &gMutex); TRACE("DosOpenMutexSem = %lu\n", arc); if (arc == NO_ERROR) { /* * Init is (being) done by another process, request the mutex to * guarantee shared memory is already alloated, then get access to * it and open shared heap located in that memory. */ arc = DosRequestMutexSem(gMutex, SEM_INDEFINITE_WAIT); ASSERT_MSG(arc == NO_ERROR, "%ld", arc); if (arc == NO_ERROR) { arc = DosGetNamedSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, PAG_READ | PAG_WRITE); TRACE("DosGetNamedSharedMem = %lu\n", arc); if (arc) { /* * This failure means that another process was too fast to do what * it wanted and initiated global uninitialization before we got the * mutex so shared memory was already freed by this time. Retry. */ DosReleaseMutexSem(gMutex); DosCloseMutexSem(gMutex); continue; } /* * It's an ordinary LIBCx process. Increase coutners. */ TRACE("gpData->heap = %p\n", gpData->heap); ASSERT(gpData->heap); rc = _uopen(gpData->heap); ASSERT_MSG(rc == 0, "%d (%d)", rc, errno); ASSERT(gpData->refcnt); gpData->refcnt++; TRACE("gpData->refcnt = %d\n", gpData->refcnt); } break; } if (arc == ERROR_SEM_NOT_FOUND) { /* We are the first process, create the mutex */ arc = DosCreateMutexSem(MUTEX_LIBCX, &gMutex, 0, TRUE); TRACE("DosCreateMutexSem = %ld\n", arc); if (arc == ERROR_DUPLICATE_NAME) { /* Another process is faster, attempt to open the mutex again */ continue; } } ASSERT_MSG(arc == NO_ERROR, "%ld", arc); /* * It's a process that successfully created the main mutex, i.e. the first * LIBCx process. Proceed with the initial setup by allocating shared * memory and heap. */ /* Allocate shared memory */ arc = DosAllocSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, HEAP_SIZE, PAG_READ | PAG_WRITE | OBJ_ANY); TRACE("DosAllocSharedMem(OBJ_ANY) = %ld\n", arc); if (arc && arc != ERROR_ALREADY_EXISTS) { /* High memory may be unavailable, try w/o OBJ_ANY */ arc = DosAllocSharedMem((PPVOID)&gpData, SHAREDMEM_LIBCX, HEAP_SIZE, PAG_READ | PAG_WRITE); TRACE("DosAllocSharedMem = %ld\n", arc); } ASSERT_MSG(arc == NO_ERROR, "%ld", arc); TRACE("gpData %p\n", gpData); /* Commit the initial block */ arc = DosSetMem(gpData, HEAP_INIT_SIZE, PAG_DEFAULT | PAG_COMMIT); ASSERT_MSG(arc == NO_ERROR, "%ld", arc); gpData->size = HEAP_INIT_SIZE; /* Create shared heap */ gpData->heap = _ucreate(gpData + 1, HEAP_INIT_SIZE - sizeof(*gpData), _BLOCK_CLEAN, _HEAP_REGULAR | _HEAP_SHARED, mem_alloc, NULL); TRACE("gpData->heap = %p\n", gpData->heap); ASSERT(gpData->heap); rc = _uopen(gpData->heap); ASSERT_MSG(rc == 0, "%d (%d)", rc, errno); gpData->refcnt = 1; /* Initialize common structures */ GLOBAL_NEW_ARRAY(gpData->procs, PROC_DESC_HASH_SIZE); TRACE("gpData->procs = %p\n", gpData->procs); ASSERT(gpData->procs); GLOBAL_NEW_ARRAY(gpData->files, FILE_DESC_HASH_SIZE); TRACE("gpData->files = %p\n", gpData->files); ASSERT(gpData->files); break; } /* * Perform common initialization (both for the first and ordinary processes). */ /* Make sure a process description for this process is created */ ProcDesc *proc = get_proc_desc(getpid()); ASSERT(proc); /* Initialize individual components */ mmap_init(proc); fcntl_locking_init(proc); /* Check if it's a spawn2 wrapper (e.g. spawn2-wrapper.c) */ { char dll[CCHMAXPATH + sizeof(SPAWN2_WRAPPERNAME) + 1]; if (get_module_name(dll, sizeof(dll))) { strcpy(_getname(dll), SPAWN2_WRAPPERNAME); char exe[CCHMAXPATH + 1]; if (_execname(exe, sizeof(exe)) == 0 && stricmp(dll, exe) == 0) { proc->flags |= Proc_Spawn2Wrapper; TRACE("spawn2 wrapper\n"); /* Make sure the semaphore is available (needed for spawn2-wrapper.c) */ ASSERT(gpData->spawn2_sem); global_spawn2_sem(proc); } } } DosReleaseMutexSem(gMutex); TRACE("done\n"); }