Beispiel #1
0
header_t* heap_alloc(size_t size) {
    header_t* h = free_list;
    header_t* best_fit = NULL;
    header_t* prev_best_fit = NULL;
    header_t* prev = NULL;

    HEAP_VALIDATE;

    // Also allocate mem for header:
    size += HEAP_HEADER_SIZE;

    // Find best candidate:
    while (h != NULL) {
        if (h->e.size >= size) {
            // h fulfils the request, but is it the best:
            if (best_fit != NULL) {
                if (h->e.size < best_fit->e.size) {
                    prev_best_fit = prev;
                    best_fit = h;
                }
            } else {
                prev_best_fit = prev;
                best_fit = h;
            }
        }
        prev = h;
        h = h->e.next;
    }

    if (best_fit != NULL) {
        // remove from free list:
        list_remove(&free_list, prev_best_fit, best_fit);

        size_t remaining_size = best_fit->e.size - size;
        size_t best_fit_size;

        if (remaining_size > HEAP_HEADER_SIZE) {
            // The best_fit is too large; split into two parts:
            header_t* remaining = offset_header(best_fit, size);
            init_element(remaining, remaining_size, HT_FREE);

            // Return to free list:
            list_insert_ordered(&free_list, remaining);

            // Adjust the size of best fit:
            best_fit_size = size;
        } else {
            // No split:
            best_fit_size = best_fit->e.size;
        }
        // else: Perfect fit
        init_element(best_fit, best_fit_size, HT_USED);
    }
    // else: Out of mem
    HEAP_VALIDATE;

    return best_fit;
}
/*main program*/
int main(int argc, char * argv[])
{
    /* Init */
    int ret;
    int mpi_rank, mpi_size;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);

    ret = starpu_init(NULL);
    STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
    ret = starpu_mpi_init(NULL, NULL, 0);
    STARPU_CHECK_RETURN_VALUE(ret, "starpu_mpi_init");

    /*element initialization : domains are connected as a ring for this test*/
    int num_elements=NUM_EL;
    struct element * el_left=malloc(num_elements*sizeof(el_left[0]));
    struct element * el_right=malloc(num_elements*sizeof(el_right[0]));
    int i;
    for(i=0; i<num_elements; i++)
    {
        init_element(el_left+i,i+1,((mpi_rank-1)+mpi_size)%mpi_size);
        init_element(el_right+i,i+1,(mpi_rank+1)%mpi_size);
    }

    /* Communication loop */
    for (i=0; i<NUM_LOOPS; i++) //number of "computations loops"
    {
        int e;
        for (e=0; e<num_elements; e++) //Do something for each elements
        {
            insert_work_for_one_element(el_right+e);
            insert_work_for_one_element(el_left+e);
        }
    }
    /* End */
    starpu_task_wait_for_all();

    for(i=0; i<num_elements; i++)
    {
        free_element(el_left+i);
        free_element(el_right+i);
    }

    starpu_mpi_shutdown();
    starpu_shutdown();

    MPI_Finalize();
    FPRINTF(stderr, "No assert until end\n");
    return 0;
}
Beispiel #3
0
void heap_init(align_t* memory, size_t length) {
    heap = to_header(memory);
    heap_size = length;
    init_element(heap, length, HT_FREE);
    free_list = heap;

    HEAP_VALIDATE;
}
Beispiel #4
0
int
proc_rule(struct htx_data *phtx_info, struct ruleinfo *prule_info,
          char *wbuf, char *rbuf, struct blk_num_typ *pblk_num)
{
  int            dlen, loop, rc;                   
  char           msg[220], path[100];
  unsigned short seed[3];

  rc = 0;
  init_seed(seed);            /* initialize seed for random number generator */
  dlen = prule_info->num_blks * BLK_SIZE;       /* initialize length of data */
                                           /*-------------------------------*/
                                           /* initialize the write buffer   */
                                           /*-------------------------------*/
  if ( (prule_info->pattern_id[0] != '#') && 
       (prule_info->pattern_id[0] != 0) ) {
	 path[0] ='\0';	  
     if ( (int) htx_strlen((char *) htx_strcpy(path, getenv("HTXPATTERNS"))) == 0 )
        htx_strcpy(path, "../pattern/");         /* default ONLY */
     htx_strcat (path, prule_info->pattern_id);
     rc = hxfpat(path, wbuf, dlen);
     if ( rc == 1 ) {
        sprintf(msg, "cannot open pattern file - %s\n", path);
        hxfmsg(phtx_info, 0, SYSERR, msg);
        return(1);
     } 
     if ( rc == 2 ) {
        sprintf(msg, "cannot read pattern file - %s\n", path);
        hxfmsg(phtx_info, 0, SYSERR, msg);
        return(1);
     } 
  } else if ( prule_info->pattern_id[0] == '#' )
     bldbuf((unsigned short*)wbuf, dlen, prule_info->pattern_id, pblk_num);
  pblk_num->in_rule = 0;      /* initialize block number within current rule */
  rc = 0;
  tape_error_code = 0;
  for ( loop = 1; loop <= prule_info->num_oper; loop++ ) {
     if ( strcmp(prule_info->oper, "R") == 0 ) {     
        rc = read_tape(phtx_info, prule_info, loop, pblk_num, rbuf);
     } else if ( strcmp(prule_info->oper, "W") == 0 ) {
        rc = write_tape(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "RC") == 0 ) {   
        rc = read_tape(phtx_info, prule_info, loop, pblk_num, rbuf);
        if ( rc >= 0 )     
           rc = cmpbuf(phtx_info, prule_info, loop, pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "RW") == 0 ) {
        rc = rewind_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "WEOF") == 0 ) { 
        rc = weof_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "SF") == 0 ) {  
        rc = search_file(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "SR") == 0 ) {  
        rc = search_rec(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "D") == 0 ) { 
        rc = diag_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "E") == 0 ) { 
        rc = erase_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "S") == 0 ) { 
        rc = do_sleep(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "CO") == 0 ) { 
        rc = close_open(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "C") == 0 ) { 
        rc = tclose(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "O") == 0 ) {  
        rc = topen(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "WEOT") == 0 ) {
        rc = write_eot(phtx_info, prule_info,loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "RCEOT") == 0 ) {
        rc = read_eot(phtx_info, prule_info, loop,pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "REOT") == 0 ) {  
        rc = read_teot(phtx_info, prule_info, loop, pblk_num, wbuf, rbuf);
     } else if ( strcmp(prule_info->oper, "RS") == 0 ) {  
        rc = prt_req_sense(phtx_info, prule_info, loop, pblk_num);
	 }
#ifndef __HTX_LINUX__		
     else if ( strcmp(prule_info->oper, "ML") == 0 ) { 
        rc = medium_load(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "MUL") == 0 ) {   
        rc = medium_unload(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "RES") == 0 ) {   
        rc = read_status(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "IE") == 0 ) {   
        rc = init_element(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "RP") == 0 ) {  
        rc = read_posit(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "LB") == 0 ) {   
        rc = loc_block(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ASF") == 0 ) { 
        rc = asearch_file(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ASR") == 0 ) { 
        rc = asearch_rec(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "ADUL") == 0 ) {  
        rc = write_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "TWIE") == 0 ) {  
        rc = twin_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWPE") == 0 ) {   
        rc = twps_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWRE") == 0 ) {  
        rc = twrd_stat(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWMM") == 0 ) { 
        rc = twmv_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "TWUL") == 0 ) {  
        rc = unload_write(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "WUL") == 0 ) {   
        rc = tape_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "CDRE") == 0 ) {
        rc = cdrd_stat(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "CDMM") == 0 ) {  
        rc = cdmv_tape(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HUNL") == 0 ) {
        rc = himove(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HINI") == 0 ) {
        rc = hiinit(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HREL") == 0 ) {
        rc = hielem(phtx_info, prule_info, loop, pblk_num);
     } else if ( strcmp(prule_info->oper, "HWUN") == 0 ) {
        rc = hidal_unload(phtx_info, prule_info, loop, pblk_num, wbuf);
     } else if ( strcmp(prule_info->oper, "DBUG") == 0 ) {  
       rc = set_dbug(phtx_info, prule_info, pblk_num);
     } 
#endif
	 else if ( strcmp(prule_info->oper, "XCMD") == 0 ) {
       rc = do_cmd(phtx_info, prule_info, pblk_num);
     } else {
        ;
     }
     hxfupdate(UPDATE, phtx_info);
     if ( phtx_info->run_type[0] == 'O' ) {
        info_msg(phtx_info, prule_info, loop, pblk_num, msg);
        hxfmsg(phtx_info, 0, INFO, msg);
     } 
     if ( rc != 0 )
        break;
  } 
  return(rc);
} 
Beispiel #5
0
static void 
read_box(FILE *fob, mxArray **data, double dbu_to_uu)
{
   mxArray *pstruct;
   mxArray *pprop = NULL;
   uint16_t rtype, rlen;
   int nprop = 0;
   element_t box;
   const char *fields[] = {"internal", "xy", "prop"};


   /* initialize element */
   init_element(&box, GDS_BOX);

   /* output data structure */
   pstruct = mxCreateStructMatrix(1,1, 3, fields);

   /* read element properties */
   while (1) {
      
      if ( read_record_hdr(fob, &rtype, &rlen) )
	 mexErrMsgTxt("gds_read_element (box) :  could not read record header.");

      if (rtype == ENDEL)
	 break;

      switch (rtype) {

         case XY:
	    mxSetFieldByNumber(pstruct, 0, 1, read_xy(fob, rlen, dbu_to_uu));
	    break;

         case LAYER:
	    box.layer = read_layer(fob);
	    break;

         case BOXTYPE:
	    box.dtype = read_type(fob);
	    break;

         case ELFLAGS:
	    box.elflags = read_elflags(fob);
	    box.has |= HAS_ELFLAGS;
	    break;

         case PLEX:
	    box.plex = read_plex(fob);
	    box.has |= HAS_PLEX;
	    break;

         case PROPATTR:
	    pprop = resize_property_structure(pprop, nprop+1);
	    mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob));
	    break;

         case PROPVALUE:
 	    mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen));
	    nprop += 1;
	    break;

         default:
	    mexPrintf("Unknown record id: 0x%x\n", rtype);
	    mexErrMsgTxt("BOX :  found unknown element property.");
      }
   }

   /* set prop field */
   if ( nprop ) {
      mxSetFieldByNumber(pstruct, 0, 2, pprop);
   }
   else {
      mxSetFieldByNumber(pstruct, 0, 2, empty_matrix());
   }

   /* store structure with element data */
   mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&box));

   /* return data */
   *data = pstruct;
}
Beispiel #6
0
static void 
read_text(FILE *fob, mxArray **data, double dbu_to_uu)
{
   mxArray *pstruct;
   mxArray *pprop = NULL;
   uint16_t rtype, rlen;
   int nprop = 0;
   char tstr[TXTLEN+4];
   element_t text;
   const char *fields[] = {"internal", "xy", "prop", "text"};


   /* initialize element */
   init_element(&text, GDS_TEXT);

   /* output data structure */
   pstruct = mxCreateStructMatrix(1,1, 4, fields);

   /* read element properties */
   while (1) {
      
      if ( read_record_hdr(fob, &rtype, &rlen) )
	 mexErrMsgTxt("gds_read_element (text) :  could not read record header.");

      if (rtype == ENDEL)
	 break;

      switch (rtype) {

         case STRING:
	    if ( read_string(fob, tstr, rlen) )
	       mexErrMsgTxt("gds_read_element (text) :  could not read string.");
	    struct_set_string(pstruct, 3, tstr);
	    break;

         case TEXTTYPE:
	    text.dtype = read_type(fob);
	    break;

         case XY:
	    mxSetFieldByNumber(pstruct, 0, 1, read_xy(fob, rlen, dbu_to_uu));
	    break;

         case LAYER:
	    text.layer = read_layer(fob);
	    break;

         case PATHTYPE:
	    text.ptype = read_type(fob);
	    text.has |= HAS_PTYPE;
	    break;

         case WIDTH:
	    text.width = dbu_to_uu * read_width(fob);
	    text.has |= HAS_WIDTH;
	    break;

         case PRESENTATION:
	    if ( read_word(fob, &text.present) )
	       mexErrMsgTxt("gds_read_element (text) :  could not read presentation data.");
	    text.has |= HAS_PRESTN;
	    break;

         case STRANS:
	    if ( read_word(fob, &text.strans.flags) )
	       mexErrMsgTxt("gds_read_element (text) :  could not read strans data.");
	    text.has |= HAS_STRANS;
	    break;

         case MAG:
	    if ( read_real8(fob, &text.strans.mag) )
	       mexErrMsgTxt("gds_read_element (text) :  could not read magnification.");
	    text.has |= HAS_MAG;
	    break;

         case ANGLE:
	    if ( read_real8(fob, &text.strans.angle) )
	       mexErrMsgTxt("gds_read_element (text) :  could not read angle.");
	    text.has |= HAS_ANGLE;
	    break;

         case ELFLAGS:
	    text.elflags = read_elflags(fob);
	    text.has |= HAS_ELFLAGS;
	    break;

         case PLEX:
	    text.plex = read_plex(fob);
	    text.has |= HAS_PLEX;
	    break;

         case PROPATTR:
	    pprop = resize_property_structure(pprop, nprop+1);
	    mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob));
	    break;

         case PROPVALUE:
 	    mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen));
	    nprop += 1;
	    break;

         default:
	    mexPrintf("Unknown record id: 0x%x\n", rtype);
	    mexErrMsgTxt("TEXT :  found unknown element property.");
      }
   }

   /* set prop field */
   if ( nprop ) {
      mxSetFieldByNumber(pstruct, 0, 2, pprop);
   }
   else {
      mxSetFieldByNumber(pstruct, 0, 2, empty_matrix());
   }

   /* store structure with element data */
   mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&text));

   /* return data */
   *data = pstruct;
}
Beispiel #7
0
static void 
read_aref(FILE *fob, mxArray **data, double dbu_to_uu)
{
   mxArray *pstruct;
   mxArray *pprop = NULL;
   uint16_t rtype, rlen;
   int nprop = 0;
   element_t aref;
   const char *fields[] = {"internal", "xy", "prop"};


   /* initialize element */
   init_element(&aref, GDS_AREF);

   /* output data structure */
   pstruct = mxCreateStructMatrix(1,1, 3, fields);

   /* read element properties */
   while (1) {
      
      if ( read_record_hdr(fob, &rtype, &rlen) )
	 mexErrMsgTxt("gds_read_element (aref) :  could not read record header.");

      if (rtype == ENDEL)
	 break;

      switch (rtype) {

         case XY:
            mxSetFieldByNumber(pstruct, 0, 1, read_xy(fob, rlen, dbu_to_uu));
 	    break;

         case SNAME:
	    if ( read_string(fob, aref.sname, rlen) )
	       mexErrMsgTxt("gds_read_element (sref) :  could not read structure name.");
	    break;

         case COLROW:
	    read_colrow(fob, &aref.nrow, &aref.ncol);
	    break;
	    
         case STRANS:
	    if ( read_word(fob, &aref.strans.flags) )
	       mexErrMsgTxt("gds_read_element (aref) :  could not read strans data.");
	    aref.has |= HAS_STRANS;
	    break;

         case MAG:
	    if ( read_real8(fob, &aref.strans.mag) )
	       mexErrMsgTxt("gds_read_element (aref) :  could not read magnification.");
	    aref.has |= HAS_MAG;
	    break;

         case ANGLE:
	    if ( read_real8(fob, &aref.strans.angle) )
	       mexErrMsgTxt("gds_read_element (aref) :  could not read angle.");
	    aref.has |= HAS_ANGLE;
	    break;

         case ELFLAGS:
	    aref.elflags = read_elflags(fob);
	    aref.has |= HAS_ELFLAGS;
	    break;

         case PLEX:
	    aref.plex = read_plex(fob);
	    aref.has |= HAS_PLEX;
	    break;

         case PROPATTR:
	    pprop = resize_property_structure(pprop, nprop+1);
	    mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob));
	    break;

         case PROPVALUE:
 	    mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen));
	    nprop += 1;
	    break;

         default:
	    mexPrintf("Unknown record id: 0x%x\n", rtype);
	    mexErrMsgTxt("AREF :  found unknown element property.");
      }
   }

   /* set prop field */
   if ( nprop ) {
      mxSetFieldByNumber(pstruct, 0, 2, pprop);
   }
   else {
      mxSetFieldByNumber(pstruct, 0, 2, empty_matrix());
   }

   /* store structure with element data */
   mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&aref));

   /* return data */
   *data = pstruct;
} 
Beispiel #8
0
static void 
read_sref(FILE *fob, mxArray **data, double dbu_to_uu)
{
   mxArray *pstruct;
   mxArray *pprop = NULL;
   mxArray *pa;
   double *pd;
   tList xylist;
   uint16_t rtype, rlen;
   int nprop = 0;
   int mtotal = 0;
   int k, m, nle;
   element_t sref;
   const char *fields[] = {"internal", "xy", "prop"};
   xy_block vertex;


   /* initialize element */
   init_element(&sref, GDS_SREF);

   /* output data structure */
   pstruct = mxCreateStructMatrix(1,1, 3, fields);

   /* create a list for the XY data record(s) */
   if ( create_list(&xylist) == -1 )
      mexErrMsgTxt("gds_read_element (sref) :  could not create list for XY records.");

   /* read element properties */
   while (1) {
      
      if ( read_record_hdr(fob, &rtype, &rlen) )
	 mexErrMsgTxt("gds_read_element (sref) :  could not read record header.");

      if (rtype == ENDEL)
	 break;

      switch (rtype) {

         case XY:
	    m = rlen / (2*sizeof(int32_t));
	    vertex.mxy = m;
	    vertex.xy = read_xy2(fob, m, dbu_to_uu);
	    list_insert_object(xylist, &vertex, sizeof(xy_block), AFTER);
	    mtotal += m;
	    break;

         case SNAME:
	    if ( read_string(fob, sref.sname, rlen) )
	       mexErrMsgTxt("gds_read_element (sref) :  could not read structure name.");
	    break;

         case STRANS:
	    if ( read_word(fob, &sref.strans.flags) )
	       mexErrMsgTxt("gds_read_element (sref) :  could not read strans data.");
	    sref.has |= HAS_STRANS;
	    break;

         case MAG:
	    if ( read_real8(fob, &sref.strans.mag) )
	       mexErrMsgTxt("gds_read_element (sref) :  could not read magnification.");
	    sref.has |= HAS_MAG;
	    break;

         case ANGLE:
	    if ( read_real8(fob, &sref.strans.angle) )
	       mexErrMsgTxt("gds_read_element (sref) :  could not read angle.");
	    sref.has |= HAS_ANGLE;
	    break;

         case ELFLAGS:
	    sref.elflags = read_elflags(fob);
	    sref.has |= HAS_ELFLAGS;
	    break;

         case PLEX:
	    sref.plex = read_plex(fob);
	    sref.has |= HAS_PLEX;
	    break;

         case PROPATTR:
	    pprop = resize_property_structure(pprop, nprop+1);
	    mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob));
	    break;

         case PROPVALUE:
 	    mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen));
	    nprop += 1;
	    break;

         default:
	    mexPrintf("Unknown record id: 0x%x\n", rtype);
	    mexErrMsgTxt("SREF :  found unknown element property.");
      }
   }

   /* catenate XY records */
   nle = list_entries(xylist);
   if ( !nle )
      mexErrMsgTxt("gds_read_element (sref) :  element has no XY record.");
   pa = mxCreateDoubleMatrix(mtotal,2, mxREAL);
   pd = mxGetData(pa);
   list_head(xylist);
   for (k=0; k<nle; k++) {
      get_current_object(xylist, &vertex, sizeof(xy_block));
      memcpy(pd, vertex.xy, 2*vertex.mxy*sizeof(double));
      pd += 2*vertex.mxy;
      mxFree(vertex.xy);
   }
   mxSetFieldByNumber(pstruct, 0, 1, pa);
   erase_list_entries(xylist);
   delete_list(&xylist);

   /* set prop field */
   if ( nprop ) {
      mxSetFieldByNumber(pstruct, 0, 2, pprop);
   }
   else {
      mxSetFieldByNumber(pstruct, 0, 2, empty_matrix());
   }

   /* store structure with element data */
   mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&sref));

   /* return data */
   *data = pstruct;
} 
Beispiel #9
0
static void 
read_path(FILE *fob, mxArray **data, double dbu_to_uu) 
{
   mxArray *pstruct;
   mxArray *pprop = NULL;
   mxArray *pc;
   tList xylist;
   uint16_t rtype, rlen;
   int nprop = 0;
   int nle, k;
   element_t path;
   const char *fields[] = {"internal", "xy", "prop"};


   /* initialize element */
   init_element(&path, GDS_PATH);

   /* output data structure */
   pstruct = mxCreateStructMatrix(1,1, 3, fields);

   /* create a list for the XY data record(s) */
   if ( create_list(&xylist) == -1 )
      mexErrMsgTxt("gds_read_element (path) :  could not create list for XY records.");

   /* read element properties */
   while (1) {
      
      if ( read_record_hdr(fob, &rtype, &rlen) )
	 mexErrMsgTxt("gds_read_element (path) :  could not read record header.");

      if (rtype == ENDEL)
	 break;

      switch (rtype) {

         case XY:
	    if ( list_insert(xylist, read_xy(fob, rlen, dbu_to_uu), AFTER) == -1)
	       mexErrMsgTxt("gds_read_element (path) :  list insertion failed.");
	    break;

         case LAYER:
	    path.layer = read_layer(fob);
	    break;

         case PATHTYPE:
	    path.ptype = read_type(fob);
	    path.has |= HAS_PTYPE;
	    break;

         case WIDTH:
	    path.width = dbu_to_uu * (double)read_width(fob);
	    path.has |= HAS_WIDTH;
	    break;

         case BGNEXTN:
	    path.bgnextn = dbu_to_uu * read_extn(fob);
	    path.has |= HAS_BGNEXTN;
	    break;

         case ENDEXTN:
	    path.endextn = dbu_to_uu * read_extn(fob);
	    path.has |= HAS_ENDEXTN;
	    break;

         case DATATYPE:
	    path.dtype = read_type(fob);
	    break;

         case ELFLAGS:
	    path.elflags = read_elflags(fob);
	    path.has |= HAS_ELFLAGS;
	    break;

         case PLEX:
	    path.plex = read_plex(fob);
	    path.has |= HAS_PLEX;
	    break;

         case PROPATTR:
	    pprop = resize_property_structure(pprop, nprop+1);
	    mxSetFieldByNumber(pprop, nprop, 0, read_propattr(fob));
	    break;

         case PROPVALUE:
 	    mxSetFieldByNumber(pprop, nprop, 1, read_propvalue(fob,rlen));
	    nprop += 1;
	    break;

         default:
	    mexPrintf("Unknown record id: 0x%x\n", rtype);
	    mexErrMsgTxt("PATH :  found unknown element property.");
      }
   }

   /* cell array with XY records */
   nle = list_entries(xylist);
   if ( !nle )
      mexErrMsgTxt("gds_read_element (path) :  element has no XY record.");
   pc = mxCreateCellMatrix(1, nle);
   list_head(xylist);
   for (k=0; k<nle; k++)
      mxSetCell(pc, k, (mxArray *)get_current_entry(xylist, NULL));
   mxSetFieldByNumber(pstruct, 0, 1, pc);

   /* set prop field */
   if ( nprop ) {
      mxSetFieldByNumber(pstruct, 0, 2, pprop);
   }
   else {
      mxSetFieldByNumber(pstruct, 0, 2, empty_matrix());
   }

   /* store structure with element data */
   mxSetFieldByNumber(pstruct, 0, 0, copy_element_to_array(&path));

   /* return data */
   *data = pstruct;
}