<commit_before>/* g/a.c
**
*/
#include "all.h"

/* _box_count(): adjust memory count.
*/
#ifdef  U3_MEMORY_DEBUG
static void
_box_count(c3_ws siz_ws)
{
  u3R->all.fre_w += siz_ws;
  {
    c3_w end_w = _(u3a_is_north(u3R))
                  ? (u3R->hat_p - u3R->rut_p)
                  : (u3R->rut_p - u3R->hat_p);
    c3_w all_w = (end_w - u3R->all.fre_w);

    if ( all_w > u3R->all.max_w ) {
      u3R->all.max_w = all_w;
    }
  }
}
#else
static void
_box_count(c3_ws siz_ws) { u3R->all.fre_w += siz_ws; }
#endif

/* _box_slot(): select the right free list to search for a block.
*/
c3_w
_box_slot(c3_w siz_w)
{
  if ( siz_w < 8 ) {
    return 0;
  }
  else {
    c3_w i_w = 1;

    while ( 1 ) {
      if ( i_w == u3a_fbox_no ) {
        return (i_w - 1);
      }
      if ( siz_w < 16 ) {
        return i_w;
      }
      siz_w = (siz_w + 1) >> 1;
      i_w += 1;
    }
  }
}

/* _box_make(): construct a box.
*/
u3a_box*
_box_make(void* box_v, c3_w siz_w, c3_w use_w)
{
  u3a_box* box_u = box_v;
  c3_w*      box_w = box_v;

  c3_assert(siz_w >= u3a_minimum);

  box_w[0] = siz_w;
  box_w[siz_w - 1] = siz_w;
  box_u->use_w = use_w;
  c3_assert(2 != use_w);

# ifdef  U3_MEMORY_DEBUG
    box_u->cod_w = u3_Code;
    box_u->eus_w = 0;
# endif

  return box_u;
}

/* _box_attach(): attach a box to the free list.
*/
void
_box_attach(u3a_box* box_u)
{
  c3_assert(box_u->siz_w >= (1 + c3_wiseof(u3a_fbox)));
  c3_assert(0 != u3of(u3a_fbox, box_u));

#if 0
  //  For debugging, fill the box with beef.
  {
    c3_w* box_w = (void *)box_u;
    c3_w  i_w;

    for ( i_w = c3_wiseof(u3a_box); (i_w + 1) < box_u->siz_w; i_w++ ) {
      box_w[i_w] = 0xdeadbeef;
    }
  }
#endif

  _box_count(box_u->siz_w);
  {
    c3_w             sel_w = _box_slot(box_u->siz_w);
    u3p(u3a_fbox)  fre_p = u3of(u3a_fbox, box_u);
    u3p(u3a_fbox)* pfr_p = &u3R->all.fre_p[sel_w];
    u3p(u3a_fbox)  nex_p = *pfr_p;

    u3to(u3a_fbox, fre_p)->pre_p = 0;
    u3to(u3a_fbox, fre_p)->nex_p = nex_p;
    if ( u3to(u3a_fbox, fre_p)->nex_p ) {
      u3to(u3a_fbox, u3to(u3a_fbox, fre_p)->nex_p)->pre_p = fre_p;
    }
    (*pfr_p) = fre_p;
  }
}

/* _box_detach(): detach a box from the free list.
*/
void
_box_detach(u3a_box* box_u)
{
  u3p(u3a_fbox) fre_p = u3of(u3a_fbox, box_u);
  u3p(u3a_fbox) pre_p = u3to(u3a_fbox, fre_p)->pre_p;
  u3p(u3a_fbox) nex_p = u3to(u3a_fbox, fre_p)->nex_p;

  _box_count(-(box_u->siz_w));

  if ( nex_p ) {
    c3_assert(u3to(u3a_fbox, nex_p)->pre_p == fre_p);
    u3to(u3a_fbox, nex_p)->pre_p = pre_p;
  }
  if ( pre_p ) {
    c3_assert(u3to(u3a_fbox, pre_p)->nex_p == fre_p);
    u3to(u3a_fbox, pre_p)->nex_p = nex_p;
  }
  else {
    c3_w sel_w = _box_slot(box_u->siz_w);

    c3_assert(fre_p == u3R->all.fre_p[sel_w]);
    u3R->all.fre_p[sel_w] = nex_p;
  }
}

/* _me_align_pad(): pad to first point after pos_p aligned at (ald_w, alp_w).
*/
static __inline__ c3_w
_me_align_pad(u3_post pos_p, c3_w ald_w, c3_w alp_w)
{
  c3_w adj_w = (ald_w - (alp_w + 1));
  c3_p off_p = (pos_p + adj_w);
  c3_p orp_p = off_p &~ (ald_w - 1);
  c3_p fin_p = orp_p + alp_w;
  c3_w pad_w = (fin_p - pos_p);

  return pad_w;
}

/* _me_align_dap(): pad to last point before pos_p aligned at (ald_w, alp_w).
*/
static __inline__ c3_w
_me_align_dap(u3_post pos_p, c3_w ald_w, c3_w alp_w)
{
  c3_w adj_w = alp_w;
  c3_p off_p = (pos_p - adj_w);
  c3_p orp_p = (off_p &~ (ald_w - 1));
  c3_p fin_p = orp_p + alp_w;
  c3_w pad_w = (pos_p - fin_p);

  return pad_w;
}

/* _ca_box_make_hat(): in u3R, allocate directly on the hat.
*/
static u3a_box*
_ca_box_make_hat(c3_w len_w, c3_w ald_w, c3_w alp_w, c3_w use_w)
{
  c3_w    pad_w;
  u3_post all_p;
     
  if ( c3y == u3a_is_north(u3R) ) {
    all_p = u3R->hat_p;
    pad_w = _me_align_pad(all_p, ald_w, alp_w);

    u3R->hat_p += (len_w + pad_w);

    if ( u3R->hat_p >= u3R->cap_p ) {
      u3m_bail(c3__meme); return 0;
    }
  }  
  else {
    all_p = (u3R->hat_p - len_w);
    pad_w = _me_align_dap(all_p, ald_w, alp_w);
    all_p -= pad_w;
    u3R->hat_p = all_p;

    if ( u3R->hat_p <= u3R->cap_p ) {
      u3m_bail(c3__meme); return 0;
    }
  }
  return _box_make(u3a_into(all_p), (len_w + pad_w), use_w);
}

#if 0
/* _me_road_all_hat(): in u3R, allocate directly on the hat.
*/
static u3a_box*
_ca_box_make_hat(c3_w len_w, c3_w alm_w, c3_w use_w)
{
  return _box_make(_me_road_all_hat(len_w), len_w, use_w);
}<commit_msg>trim cache and retry allocation<commit_after>/* g/a.c
**
*/
#include "all.h"

/* _box_count(): adjust memory count.
*/
#ifdef  U3_MEMORY_DEBUG
static void
_box_count(c3_ws siz_ws)
{
  u3R->all.fre_w += siz_ws;
  {
    c3_w end_w = _(u3a_is_north(u3R))
                  ? (u3R->hat_p - u3R->rut_p)
                  : (u3R->rut_p - u3R->hat_p);
    c3_w all_w = (end_w - u3R->all.fre_w);

    if ( all_w > u3R->all.max_w ) {
      u3R->all.max_w = all_w;
    }
  }
}
#else
static void
_box_count(c3_ws siz_ws) { u3R->all.fre_w += siz_ws; }
#endif

/* _box_slot(): select the right free list to search for a block.
*/
c3_w
_box_slot(c3_w siz_w)
{
  if ( siz_w < 8 ) {
    return 0;
  }
  else {
    c3_w i_w = 1;

    while ( 1 ) {
      if ( i_w == u3a_fbox_no ) {
        return (i_w - 1);
      }
      if ( siz_w < 16 ) {
        return i_w;
      }
      siz_w = (siz_w + 1) >> 1;
      i_w += 1;
    }
  }
}

/* _box_make(): construct a box.
*/
u3a_box*
_box_make(void* box_v, c3_w siz_w, c3_w use_w)
{
  u3a_box* box_u = box_v;
  c3_w*      box_w = box_v;

  c3_assert(siz_w >= u3a_minimum);

  box_w[0] = siz_w;
  box_w[siz_w - 1] = siz_w;
  box_u->use_w = use_w;
  c3_assert(2 != use_w);

# ifdef  U3_MEMORY_DEBUG
    box_u->cod_w = u3_Code;
    box_u->eus_w = 0;
# endif

  return box_u;
}

/* _box_attach(): attach a box to the free list.
*/
void
_box_attach(u3a_box* box_u)
{
  c3_assert(box_u->siz_w >= (1 + c3_wiseof(u3a_fbox)));
  c3_assert(0 != u3of(u3a_fbox, box_u));

#if 0
  //  For debugging, fill the box with beef.
  {
    c3_w* box_w = (void *)box_u;
    c3_w  i_w;

    for ( i_w = c3_wiseof(u3a_box); (i_w + 1) < box_u->siz_w; i_w++ ) {
      box_w[i_w] = 0xdeadbeef;
    }
  }
#endif

  _box_count(box_u->siz_w);
  {
    c3_w             sel_w = _box_slot(box_u->siz_w);
    u3p(u3a_fbox)  fre_p = u3of(u3a_fbox, box_u);
    u3p(u3a_fbox)* pfr_p = &u3R->all.fre_p[sel_w];
    u3p(u3a_fbox)  nex_p = *pfr_p;

    u3to(u3a_fbox, fre_p)->pre_p = 0;
    u3to(u3a_fbox, fre_p)->nex_p = nex_p;
    if ( u3to(u3a_fbox, fre_p)->nex_p ) {
      u3to(u3a_fbox, u3to(u3a_fbox, fre_p)->nex_p)->pre_p = fre_p;
    }
    (*pfr_p) = fre_p;
  }
}

/* _box_detach(): detach a box from the free list.
*/
void
_box_detach(u3a_box* box_u)
{
  u3p(u3a_fbox) fre_p = u3of(u3a_fbox, box_u);
  u3p(u3a_fbox) pre_p = u3to(u3a_fbox, fre_p)->pre_p;
  u3p(u3a_fbox) nex_p = u3to(u3a_fbox, fre_p)->nex_p;

  _box_count(-(box_u->siz_w));

  if ( nex_p ) {
    c3_assert(u3to(u3a_fbox, nex_p)->pre_p == fre_p);
    u3to(u3a_fbox, nex_p)->pre_p = pre_p;
  }
  if ( pre_p ) {
    c3_assert(u3to(u3a_fbox, pre_p)->nex_p == fre_p);
    u3to(u3a_fbox, pre_p)->nex_p = nex_p;
  }
  else {
    c3_w sel_w = _box_slot(box_u->siz_w);

    c3_assert(fre_p == u3R->all.fre_p[sel_w]);
    u3R->all.fre_p[sel_w] = nex_p;
  }
}

/* _me_align_pad(): pad to first point after pos_p aligned at (ald_w, alp_w).
*/
static __inline__ c3_w
_me_align_pad(u3_post pos_p, c3_w ald_w, c3_w alp_w)
{
  c3_w adj_w = (ald_w - (alp_w + 1));
  c3_p off_p = (pos_p + adj_w);
  c3_p orp_p = off_p &~ (ald_w - 1);
  c3_p fin_p = orp_p + alp_w;
  c3_w pad_w = (fin_p - pos_p);

  return pad_w;
}

/* _me_align_dap(): pad to last point before pos_p aligned at (ald_w, alp_w).
*/
static __inline__ c3_w
_me_align_dap(u3_post pos_p, c3_w ald_w, c3_w alp_w)
{
  c3_w adj_w = alp_w;
  c3_p off_p = (pos_p - adj_w);
  c3_p orp_p = (off_p &~ (ald_w - 1));
  c3_p fin_p = orp_p + alp_w;
  c3_w pad_w = (pos_p - fin_p);

  return pad_w;
}

/* _ca_box_make_hat(): in u3R, allocate directly on the hat.
*/
static u3a_box*
_ca_box_make_hat(c3_w len_w, c3_w ald_w, c3_w alp_w, c3_w use_w)
{
  c3_w    pad_w;
  u3_post all_p;

  if ( c3y == u3a_is_north(u3R) ) {

    //  if allocation would fail, halve the cache until we have enough space.
    while ( u3R->hat_p + len_w + _me_align_pad(u3R->hat_p, ald_w, alp_w)
            >= u3R->cap_p ) {

      //  if we can't trim any more and we're still out of loom, give up.
      if ( 0 == u3R->cax.har_p ) {
        u3m_bail(c3__meme); return 0;
      }

      u3h_trim_to(u3R->cax.har_p, u3to(u3h_root, u3R->cax.har_p)->use_w / 2);
    }

    all_p = u3R->hat_p;
    pad_w = _me_align_pad(all_p, ald_w, alp_w);

    u3R->hat_p += (len_w + pad_w);
  }  
  else {

    //  if allocation would fail, halve the cache until we have enough space.
    while ( u3R->hat_p - len_w - _me_align_dap(u3R->hat_p - len_w, ald_w, alp_w)
            <= u3R->cap_p ) {

      //  if we can't trim any omre and we're still out of loom, give up.
      if ( 0 == u3R->cax.har_p ) {
        u3m_bail(c3__meme); return 0;
      }

      u3h_trim_to(u3R->cax.har_p, u3to(u3h_root, u3R->cax.har_p)->use_w / 2);
    }

    all_p = (u3R->hat_p - len_w);
    pad_w = _me_align_dap(all_p, ald_w, alp_w);
    all_p -= pad_w;
    u3R->hat_p = all_p;
  }
  return _box_make(u3a_into(all_p), (len_w + pad_w), use_w);
}

#if 0
/* _me_road_all_hat(): in u3R, allocate directly on the hat.
*/
static u3a_box*
_ca_box_make_hat(c3_w len_w, c3_w alm_w, c3_w use_w)
{
  return _box_make(_me_road_all_hat(len_w), len_w, use_w);
}
{'fraction_non_alphanumeric': 0.15170736864361983, 'fraction_numerical': 0.03594460302357543, 'mean_word_length': 2.7554585152838427, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 105, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '58304', 'n_tokens_mistral': 5149, 'n_tokens_neox': 5015, 'n_words': 897}