/***************************************************************************
 * Copyright 1995, Technion, Israel Institute of Technology
 * Electrical Eng, Software Lab.
 * Author:    Michael Veksler.
 ***************************************************************************
 * File:      dde_mem.c
 * Purpose :  shared DDE memory functionality for DDE
 ***************************************************************************
 */
#include <stdio.h>
#include <stddebug.h>
#include <debug.h>
#include <assert.h>
#include "ldt.h"
#include "shm_main_blk.h"
#include "shm_fragment.h"
#include "shm_semaph.h"
#include "dde_mem.h"
#include "bit_array.h"

#define SEGPTR2HANDLE_INFO(sptr) ( (struct handle_info*)PTR_SEG_TO_LIN(sptr) )

#define HINFO2DATAPTR(h_info_ptr) ( (void*) ( (char*)h_info_ptr +           \
					     sizeof(struct handle_info) ) )
#define DDE_MEM_IDX(handle) ((handle)& 0x7fff)
#define DDE_MEM_HANDLE(idx) ((idx) | 0x8000)
#define DDE_MEM_INFO(handle) (main_block->handles[ DDE_MEM_IDX(handle) ])
/* List of shared handles.
 * This entry resides on the shared memory, the data comes right
 * after the `handle_info'.
 * The entry is on the same block as the actual data.
 * The `next' field gives relative reference (relative to the start of
 * the blcok.
 */
struct handle_info {
	WORD lock_count;
	WORD flags;
	int size;		/* size of the data (net)*/
};

static bit_array free_handles;
int debug_last_handle_size= 0;	/* for debugging purpose only */


/* locate_handle:
 *   locate a shared memory handle.
 * Application:
 *   The handle is first searched for in attached blocks.
 *   At the beginning, only blocks owned by this process are
 *   attached.
 *   If a handle is not found, new blocks are attached.
 * Arguments:
 *   h    - the handle.
 * RETURN: pointer to handle info.
 */
static struct handle_info *locate_handle(HGLOBAL h, struct local_shm_map *map)
{
  struct shm_block *block;
  
  dprintf_global(stddeb,"shm:locate_handle(0x%04x)\n", h);


  if (SampleBit( &free_handles, DDE_MEM_IDX(h)) == 0) {
     dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
     return NULL;		   /* free!!! */
  }
  
  block= shm_locate_block(DDE_MEM_INFO(h).shmid, map);
  if (block == NULL) {
      /* nothing found */
      dprintf_global(stddeb, "shm:locate_handle: return NULL\n");
      return NULL;
  }

  return (struct handle_info *) REL2PTR(block, DDE_MEM_INFO(h).rel);
  
}

/* dde_alloc_handle: allocate shared DDE handle */
static HGLOBAL dde_alloc_handle()
{
  int bit_nr;

  bit_nr= AllocateBit( &free_handles);

  if (bit_nr != -1)
     return DDE_MEM_HANDLE(bit_nr);

  dprintf_global(stddeb,"dde_alloc_handle: no free DDE handle found\n");
  return 0;
}
/**********************************************************************
 *					DDE_malloc
 */
void *
DDE_malloc(unsigned int flags, unsigned long size, SHMDATA *shmdata)
{
    int shmid;
    struct shm_block *block;
    struct handle_info *h_info;
    struct local_shm_map *curr;
    HGLOBAL handle;
    
    dprintf_global(stddeb,"DDE_malloc flags %4X, size %ld\n", flags, size);
    DDE_IPC_init();		/* make sure main shm block allocated */ 

    shm_write_wait(main_block->proc[curr_proc_idx].sem);

    /* Try to find fragment big enough for `size' */
    /* iterate through all local shm blocks, and try to allocate
       the fragment */

    h_info= NULL;
    for (curr=  shm_map ; curr != NULL ; curr= curr->next) {
       if (curr->proc_idx == curr_proc_idx) {
	  h_info= (struct handle_info *)
	     shm_FragPtrAlloc(curr->ptr, size+sizeof(struct handle_info));
	  if (h_info!=NULL) {
	     shmid= curr->shm_id;
	     break;
	  }
       }
    }

    if (h_info == NULL) {
       
       block= shm_create_block(0, size+sizeof(struct handle_info), &shmid);
       if (block==NULL) {
	  shm_write_signal(main_block->proc[curr_proc_idx].sem);
	  return 0;
       }
       /* put the new block in the linked list */
       block->next_shm_id= main_block->proc[curr_proc_idx].shmid;
       main_block->proc[curr_proc_idx].shmid= shmid;
       h_info= (struct handle_info *)
	  shm_FragPtrAlloc(block, size+sizeof(struct handle_info));
       if (h_info==NULL) {
	  fprintf(stderr,"DDE_malloc: BUG! unallocated fragment\n");
	  shm_write_signal(main_block->proc[curr_proc_idx].sem);
	  return 0;
       }
    } else {
       block= curr->ptr;
    }

    /* Here we have an allocated fragment */
    h_info->flags= flags;
    h_info->lock_count= 0;
    h_info->size= size;
    handle= dde_alloc_handle();
    
    if (handle) {
       dprintf_global(stddeb,
		      "DDE_malloc returning handle=0x%4x, ptr=0x%08lx\n",
		      (int)handle, (long) HINFO2DATAPTR(h_info));
       DDE_MEM_INFO(handle).rel=  PTR2REL(block, h_info);
       DDE_MEM_INFO(handle).shmid= shmid;
    }
    else
       dprintf_global(stddeb,"DDE_malloc failed\n");

    shm_write_signal(main_block->proc[curr_proc_idx].sem);
    
    shmdata->handle= handle;
    return (char *)HINFO2DATAPTR(h_info);
}

HGLOBAL DDE_GlobalFree(HGLOBAL h)
{
  struct handle_info *h_info;
  int handle_index= h & 0x7fff;
  struct local_shm_map map;

  dprintf_global(stddeb,"DDE_GlobalFree(0x%04x)\n",h);

  if (h==0)
     return 0;

  h_info= locate_handle(h, &map);
  if (h_info == NULL)
      return h;

  shm_write_wait(main_block->proc[map.proc_idx].sem);

  shm_FragPtrFree(map.ptr, (struct shm_fragment *) h_info);

  AssignBit( &free_handles, handle_index, 0);
  
  /* FIXME: must free the shm block some day. */
  shm_write_signal(main_block->proc[map.proc_idx].sem);
  return 0;
}

WORD DDE_SyncHandle(HGLOBAL handle, WORD sel)
    
{
    struct handle_info *h_info;
    void *local_ptr;
    ldt_entry entry;
    
    h_info= locate_handle(handle, NULL);
    local_ptr= (void *)GET_SEL_BASE(sel);

    
    if (h_info == NULL)
	return 0;
    
    if (local_ptr == (void *) HINFO2DATAPTR(h_info))
	return sel;

    /* need syncronization ! */
    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
    entry.base= (unsigned long) HINFO2DATAPTR(h_info);
    LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );

    return sel;
}

/*
 * DDE_AttachHandle:
 * Attach shm memory (The data must not be already attached).
 * Parameters:
 *   handle - the memory to attach.
 *   segptr - in not null, return SEGPTR to the same block.
 * return value:
 *   32 bit pointer to the memory.
 */

void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr)
{
  struct handle_info *h_info;
  SHMDATA shmdata;
  void *ptr;
  HGLOBAL hOwner = GetCurrentPDB();

  assert(is_dde_handle(handle));
  if (segptr != NULL)
      *segptr=0;

  dprintf_global(stddeb,"DDE_AttachHandle(%04x)\n",handle);
  h_info=locate_handle(handle, NULL);

  if (h_info == NULL) 
      return NULL;

  if ( !(h_info->flags & GMEM_DDESHARE) ) {
      fprintf(stderr,"DDE_AttachHandle: Corrupted memory handle info\n");
      return NULL;
  }
  
  dprintf_global(stddeb,"DDE_AttachHandle: h_info=%06lx\n",(long)h_info);

  shmdata.handle= handle;
  shmdata.shmid= DDE_MEM_INFO(handle).shmid;

  ptr= HINFO2DATAPTR(h_info);
  /* Allocate the selector(s) */
  if (! GLOBAL_CreateBlock( h_info->flags, ptr, h_info->size, hOwner,
			    FALSE, FALSE, FALSE, &shmdata)) 
      return NULL;

  if (segptr != NULL) 
      *segptr= (SEGPTR)MAKELONG( 0, shmdata.sel);

  if (debugging_dde)
      debug_last_handle_size= h_info->size;

  dprintf_global(stddeb,"DDE_AttachHandle returns ptr=0x%08lx\n", (long)ptr);

  return (LPSTR)ptr;

}

void DDE_mem_init()
{
  int nr_of_bits;

  shm_init();
  
  nr_of_bits= BITS_PER_BYTE * sizeof(main_block->free_handles);
  AssembleArray( &free_handles, main_block->free_handles, nr_of_bits);
}
