/***************************************************************************
 * 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 <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);
}

#endif  /* CONFIG_IPC */
