Subversion Repositories shark

Rev

Rev 498 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <FTrace_chunk.h>
#include <FTrace_types.h>
#include <FTrace_OSD.h>

#define FTRACE_DEBUG

/* Globals */

FTrace_Chunk_Ptr ChunkTable[MAX_CHUNK]; /* Chunk array */
FTrace_Chunk_Ptr ActualChunk = NULL; /* Actual Chunk */

/* Global Pointers */
BYTE OSD_pointers[FTRACE_OSD_CHUNK_HEAD];

int              FTraceInit   = 0;
int              FTraceEnable = 0;

/* Init a chunk with default value */
static int FTrace_chunk_init(FTrace_Chunk_Ptr c, int number, int size, FTrace_flags flags)
{

  c->id       = FTRACE_CHUNK_ID; /* Std ID */
  c->number   = number; /* Chunk number */
  c->flags    = flags; /* Chunk flags */
  c->size     = size; /* Chunk real size */
  c->sizemask = size - 1; /* Chunk data size mask */
  c->osd      = (DWORD)((DWORD)(c) + sizeof(struct FTrace_Chunk));
 
  return FTrace_OSD_chunk_init(c, size, flags);

}

/* Find a free slot in ChunkTable */
static int FTrace_find_free_slot()
{

  int i;

  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    return -1;
  }

  for (i = 0;i < MAX_CHUNK;i++)
    if (ChunkTable[i] == NULL)
      return i;

  return -1;
   
}

/* Init the FTrace */
static int FTrace_Init()
{

  int i,err;

  /* Check if it's just initialized */
  if (FTraceInit == 1)
    return 0;

  FTrace_lock();

  memset(OSD_pointers,0,sizeof(OSD_pointers));

  for (i = 0;i < MAX_CHUNK;i++)
    ChunkTable[i] = NULL;

  /* Init System Dependet Part */
  err = FTrace_OSD_init();
  if (err != 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace OSD not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  FTraceInit = 1;

  FTrace_unlock();

  return 0;

}

/* Enable Tracer */
int FTrace_enable()
{

  if (FTraceInit == 0 || ActualChunk == NULL) return -1;

  FTrace_fsave();
    FTraceEnable = 1;
  FTrace_frestore();

  return 0;

}

/* Disable Tracer */
int FTrace_disable()
{
                                                                                                                             
  if (FTraceInit == 0) return -1;
                                                                                                                             
  FTrace_fsave();
    FTraceEnable = 0;
  FTrace_frestore();
                                                                                                                             
  return 0;
                                                                                                                             
}

/* Create n chunks of specified size, where size = 2^bits */
int FTrace_chunk_create(int n, int bits, FTrace_flags flags)
{

  FTrace_Chunk_Ptr FT_temp;
  int i, number, err, size;

  FTrace_lock();

  if (FTraceInit == 0) {
    err = FTrace_Init();
    if (err != 0) {
      #ifdef FTRACE_DEBUG
        FTrace_printf("FTrace Error: Initialization fail\n");
      #endif
      FTrace_unlock();
      return -1;
    }
  }

  /* Get size */
  size = 1 << bits;

  for (i = 0;i < n;i++) {

    number = FTrace_find_free_slot();
    if (number == -1) {
      #ifdef FTRACE_DEBUG
        FTrace_printf("FTrace Error: cannot find free slot for chunk\n");
      #endif
      FTrace_unlock();
      return -1;
    }

    FT_temp = (FTrace_Chunk_Ptr)FTrace_malloc(sizeof(struct FTrace_Chunk) + FTRACE_OSD_CHUNK_HEAD + size);
    if (FT_temp == NULL) {
      #ifdef FTRACE_DEBUG
        FTrace_printf("FTrace Error: cannot allocate memory for chunk\n");
      #endif
      FTrace_unlock();
      return -1;
    }

    err = FTrace_chunk_init(FT_temp, number, size, flags);
    if (err != 0) {
      #ifdef FTRACE_DEBUG
        FTrace_printf("FTrace Error: cannot initialized the new chunk\n");
      #endif
      FTrace_unlock();
      return -1;
    }

    /* Set the ChunkTable */
    ChunkTable[number] = FT_temp;

     #ifdef FTRACE_DEBUG
       FTrace_printf("FTrace Debug: Chunk %d created at addr %x\n",number,(int)FT_temp);
     #endif

  }

  FTrace_unlock();
  return 0;

}

/* Delete a Chunk */
int FTrace_chunk_delete(int number)
{

  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];

  FTrace_lock();

  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (FT_temp->flags & FTRACE_CHUNK_FLAG_NODEL) {
    FTrace_unlock();
    return 0;
  }

  FTrace_free(FT_temp);
  ChunkTable[number] = NULL;

  FTrace_unlock();
  return 0;

}

/* Set the chunk flags */
int FTrace_set_chunk_flags(int number, FTrace_flags flags)
{
                                                                                                   
  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];
                                                                                                   
  FTrace_lock();
                                                                                                   
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  FT_temp->flags = flags;

  return 0;

}

/* Get the chunk flags */
int FTrace_get_chunk_flags(int number, FTrace_flags *flags)
{
                                                                                                   
  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];
                                                                                                   
  FTrace_lock();
                                                                                                   
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  *flags = FT_temp->flags;
                                                                                                   
  return 0;
                                                                                                   
}

/* Select the actual chunk */
int FTrace_actual_chunk_select(int number)
{

  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];
   
  FTrace_lock();
                                                                                               
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (FT_temp->flags & FTRACE_CHUNK_FLAG_FREE) {

    /* Set as used */
    FT_temp->flags &= ~FTRACE_CHUNK_FLAG_FREE;

    /* Update the actual_chunk and OSD_pointers */
    FTrace_fsave();
      FTrace_OSD_save_pointers();
      ActualChunk = FT_temp;
      FTrace_OSD_load_pointers();
    FTrace_frestore();

  } else {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk is not free\n");
    #endif
    FTrace_unlock();
    return -1;
  }
   
  FTrace_unlock();

  return 0;

}

/* Find the first chunk with specific flags*/
int FTrace_get_first_chunk(FTrace_flags flags) {

  int i;

  FTrace_lock();
                                                                                                 
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  for (i = 0;i < MAX_CHUNK;i++) {

    if (ChunkTable[i]->flags & flags) {
      FTrace_unlock();
      return i;
    }

  }

 #ifdef FTRACE_DEBUG
   FTrace_printf("FTrace Error: Free chunk not found\n");
 #endif
 FTrace_unlock();

 return -1;

}

/* Get chunk table */
FTrace_Chunk_Ptr *FTrace_get_chunk_table()
{
                                                                                                   
  return ChunkTable;
                                                                                                   
}

/* Link two chunks */
int FTrace_chunk_link(int chunk_A, int chunk_B, int osd_flags)
{

  FTrace_Chunk_Ptr ckA = ChunkTable[chunk_A];
  FTrace_Chunk_Ptr ckB = ChunkTable[chunk_B];

  int err;
                                                                                                                             
  FTrace_lock();
                                                                                                                             
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                                             
  if (ckA == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk A not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (ckB == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk B not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (!(ckB->flags & FTRACE_CHUNK_FLAG_FREE)) {
    ckB->flags &= ~FTRACE_CHUNK_FLAG_FREE;
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk B is not free\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  /* FTrace Low Level Blocking Part */
  FTrace_fsave();
    FTrace_OSD_save_pointers();

    err = FTrace_OSD_chunk_link(ckA,ckB,osd_flags);
    if (err != 0) {
      #ifdef FTRACE_DEBUG
        FTrace_printf("FTrace Error: Cannot link the chunks\n");
      #endif
      return -1;
    }

    FTrace_OSD_load_pointers();
  FTrace_frestore();

  FTrace_unlock();

  return 0;

}

/* Create a new memory region where the compressed data are stored */
int FTrace_compress_chunk(int number, FTrace_flags new_flags)
{
  void *temp_data;
  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];
  int err, data_size;
  FTrace_Chunk_Ptr New_chunk;

  FTrace_lock();
                                                                                                   
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  FT_temp->flags |= FTRACE_CHUNK_FLAG_BUSY;

  FTrace_unlock();

  /* Alloc temp memory for */
  temp_data = (void *)FTrace_malloc(FT_temp->sizemask+1);
  if (temp_data == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Cannot allocate memory\n");
    #endif
    return -1;
  }

  /* Compress the chunk. Temp_data are a temporary region where
     store the compressed chunk. Data_size is the size of compressed
     data */

  err = FTrace_OSD_compress_chunk(number,temp_data,&data_size);
  if (err != 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: OSD Compressing function failed\n");
    #endif
    return -1;
  }

  New_chunk = (FTrace_Chunk_Ptr)FTrace_malloc(sizeof(struct FTrace_Chunk) + FTRACE_OSD_CHUNK_HEAD + data_size);
  if (New_chunk == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Cannot allocate memory\n");
    #endif
    return -1;
  }

  memcpy(New_chunk,temp_data,data_size);

  FTrace_free(temp_data);

  FTrace_lock();

  /* Free the memory of the old chunk */
  FTrace_free(FT_temp);

  /* Set the new chunk flags and update the main table */
  New_chunk->flags = new_flags;
  New_chunk->flags |= FTRACE_CHUNK_FLAG_COMPR;
  ChunkTable[number] = New_chunk;
 
  FTrace_unlock();

  return 0;

}

/* Send the chunk out from the memory */
int FTrace_send_chunk(int number, int osd_flags, FTrace_flags new_flags)
{
  FTrace_Chunk_Ptr FT_temp = ChunkTable[number];
  int err;                                
                                                                   
  FTrace_lock();
                                                                                                   
  if (FTraceInit == 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: FTrace not initialized\n");
    #endif
    FTrace_unlock();
    return -1;
  }
                                                                                                   
  if (FT_temp == NULL) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Chunk not present\n");
    #endif
    FTrace_unlock();
    return -1;
  }

  FT_temp->flags |= FTRACE_CHUNK_FLAG_BUSY;

  FTrace_unlock();

  err = FTrace_OSD_send_chunk(number, osd_flags);
  if (err != 0) {
    #ifdef FTRACE_DEBUG
      FTrace_printf("FTrace Error: Cannot send the chunk\n");
    #endif
    return -1;
  }

  FTrace_lock();
                                                                                                   
  /* Set the new chunk flags */
  FT_temp->flags = new_flags;
                                                                                                   
  FTrace_unlock();
                                                                                                   
  return 0;

}