/***************************************************************************
 * 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
 ***************************************************************************
 */
#ifdef CONFIG_IPC

#include <assert.h>
#include "debug.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(HGLOBAL16 h, struct local_shm_map *map)
{
  struct shm_block *block;
  
  TRACE(global,"shm: (0x%04x)\n", h);


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

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

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

  bit_nr= AllocateBit( &free_handles);

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

  TRACE(global,"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;
    HGLOBAL16 handle;
    
    TRACE(global,"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) {
	  ERR(global,"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) {
       TRACE(global, "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
       WARN(global, "failed\n");

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

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

  TRACE(global,"(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(HGLOBAL16 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(HGLOBAL16 handle, SEGPTR *segptr)
{
  struct handle_info *h_info;
  SHMDATA shmdata;
  void *ptr;
  HGLOBAL16 hOwner = GetCurrentPDB();

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

  TRACE(global,"(%04x)\n",handle);
  h_info=locate_handle(handle, NULL);

  if (h_info == NULL) 
      return NULL;

  if ( !(h_info->flags & GMEM_DDESHARE) ) {
      ERR(global,"Corrupted memory handle info\n");
      return NULL;
  }
  
  TRACE(global,"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 (TRACE_ON(dde))
      debug_last_handle_size= h_info->size;

  TRACE(global,"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);
}

#endif  /* CONFIG_IPC */
