/* drw mem alloc definitions. */

#ifndef drwalloc_H
#define drwalloc_H

#include "DRW/drwGPdef.h"

#ifndef osmodule_H
 #include "OSlib/osmodule.h"
#endif

#ifndef drwll_H
 #include "DRW/drwllh.h"
#endif

#if defined NAMESPACE_DRWIMPC
  namespace DrWimpC {
#endif

#if defined NAMESPACE_OSLIB
  using namespace OSLib;
#endif

typedef void (drw_data_init_fn)(void *dataptr);


#ifndef drw_mem_type
 #define drw_mem_type       unsigned int
#endif

#define DRW_NO_MEM_TYPE    0x0u
#define DRW_MEM_DA         0x1u
#define DRW_MEM_RMA        0x2u
#define DRW_MEM_MALLOC     0x4u
#define DRW_MEM_USER_FN    0x8u
#define DRW_MEM_FLEX       0x10u
#define DRW_MEM_SH         0x20u


typedef struct drw_da_str               drw_da_str;
typedef struct drw_mem_block            drw_mem_block;
typedef struct drw_mem_block_mem        drw_mem_block_mem;
typedef struct drw_mem_page_data        drw_mem_page_data;
typedef struct drw_mem_block_entry      drw_mem_block_entry;
typedef struct drw_mem_entry            drw_mem_entry;
typedef struct drw_fixed_mem_ptrs       drw_fixed_mem_ptrs;


typedef bits                            drw_da_flagwd;
typedef bits                            drw_mem_flags;
typedef bits                            drw_mem_page_hdr_flags;
typedef bits                            drw_mem_block_entry_flags;
typedef bits                            drw_mem_report_flags;


typedef unsigned int                    drw_check_wd;
/*typedef unsigned int                    drw_mem_size;*/


#define drw_store_mem_size              ((drw_da_flagwd) 0x1u)

#define drw_mem_page_is_exclusive       ((drw_mem_page_hdr_flags) 0x1u)
#define drw_mem_page_dynamic            ((drw_mem_page_hdr_flags) 0x2u)


#define drw_mem_zero_flags              ((drw_mem_flags) 0x0u)
#define drw_mem_use_wimpslot            ((drw_mem_flags) 0x1u)
#define drw_use_wslot_on_iyonix         ((drw_mem_flags) 0x2u)
#define drw_mem_exclusive               ((drw_mem_flags) 0x4u)
#define drw_mem_heap_is_dynamic         ((drw_mem_flags) 0x8u)
#define drw_mem_use_malloc              ((drw_mem_flags) 0x10u)

#define drw_check_wd_val                ((drw_check_wd) 0x3E694C3Cu)

#define drw_mem_def_block_size          ((size_t) 4096)

#define drw_mem_block_entry_in_use      ((drw_mem_block_entry_flags) 0x1u)

#define drw_min_mem_size                (sizeof(int))

#define drw_mem_blk_show_quit_msg       ((drw_mem_report_flags) 0x1u)
#define drw_mem_blk_write_to_syslog     ((drw_mem_report_flags) 0x2u)
#define drw_mem_blk_write_to_fdmem      ((drw_mem_report_flags) 0x4u)
#define drw_mem_blk_info_da_size        ((drw_mem_report_flags) 0x8u)
#define drw_mem_blk_info_reallocating   ((drw_mem_report_flags) 0x10u)
#define drw_mem_blk_info_checking_blk   ((drw_mem_report_flags) 0x20u)
#define drw_mem_blk_info_numblocks      ((drw_mem_report_flags) 0x40u)
#define drw_mem_blk_checkwd_invalid     ((drw_mem_report_flags) 0x80u)
#define drw_mem_blk_ntblock_too_big     ((drw_mem_report_flags) 0x100u)
#define drw_mem_entry_checkwd_invalid   ((drw_mem_report_flags) 0x200u)
#define drw_mem_entry_offset_ob         ((drw_mem_report_flags) 0x400u)
#define drw_mem_entry_size_lt0          ((drw_mem_report_flags) 0x800u)


struct drw_da_str {

os_dynamic_area_no danum;
byte *darea;
drw_mem_type memtype;
drw_da_flagwd flags;
int allocsize;

};


struct drw_mem_page_data {

byte blk[UNKNOWN];

};


struct drw_fixed_mem_ptrs {

drw_fixed_mem_ptrs *ntmem;
drw_fixed_mem_ptrs *prmem;

};


struct drw_mem_entry {

drw_check_wd checkwd;
size_t blkoffset;
size_t entryno;

};


/* size is the actual size of the memory requested, not a rounded up value. */
/* blkoffset is a rounded up value. */
/* prentryno and ntentryno link the block entries in the order that the */
/* memory blocks occur within the block. */


struct drw_mem_block_entry {

drwGP_ptr anchor;
size_t size;
size_t blkoffset;
size_t prentryno;
size_t ntentryno;
drw_mem_block_entry_flags flags;

};


/* There will always be 1 entry, so numentries == 1 with the in use */
/* flag not set indicates an empty block. */
/* largest is a rounded up value. */

#define drw_mem_block_mem_items \
drw_check_wd checkwd; \
size_t ntblock; \
size_t prblock; \
size_t lastblock; \
size_t blocksize; \
size_t largest; \
size_t numentries; \
size_t eob; \
drw_mem_page_hdr_flags flags; \
int numblocks;


struct drw_mem_block_mem_base {

drw_mem_block_mem_items

};


struct drw_mem_block {

drw_mem_block_mem_items
drw_mem_page_data data;

};


#define drw_mem_block_DATA(N) \
   struct \
      {  drw_mem_block_mem_base \
         byte mem [N]; \
      }

#define drw_SIZEOF_block_SIZE(N) \
   (offsetof (drw_mem_block, data) + \
         (N)*sizeof ((drw_mem_block *) NULL)->data)

#if defined NAMESPACE_DRWIMPC
  }
#endif

#include "DRW/drwalloc.h"

#endif

