예제 #1
0
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);
}
예제 #2
0
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;
  }
예제 #3
0
파일: shared.c 프로젝트: bitwiseworks/libcx
/**
 * 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");
}