예제 #1
0
uint32_t nrf_mem_init(void)
{
    MM_LOG("[MM]: >> nrf_mem_init.\r\n");

    SDK_MUTEX_INIT(m_mm_mutex);

    MM_MUTEX_LOCK();

    uint32_t block_index = 0;

    for(block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++)
    {
        block_init(block_index);
    }

#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
    m_module_initialized = true;
#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK

#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
    nrf_mem_diagnose();
#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS

    MM_MUTEX_UNLOCK();

    MM_LOG("[MM]: << nrf_mem_init.\r\n");

    return NRF_SUCCESS;
}
예제 #2
0
void nrf_free(void * p_mem)
{
    VERIFY_MODULE_INITIALIZED_VOID();
    NULL_PARAM_CHECK_VOID(p_mem);

    MM_LOG("[MM]: >> nrf_free %p.\r\n", p_mem);

    MM_MUTEX_LOCK();

    uint32_t index;
    uint32_t memory_index = 0;

    for (index = 0; index < TOTAL_BLOCK_COUNT; index++)
    {
        if (&m_memory[memory_index] == p_mem)
        {
            // Found a free block of memory, assign.
            MM_LOG("[MM]: << Freeing block %d.\r\n", index);
            block_init(index);
            break;
        }
        memory_index += get_block_size(index);
    }

    MM_MUTEX_UNLOCK();

    MM_LOG("[MM]: << nrf_free.\r\n");
    return;
}
예제 #3
0
파일: smanager.c 프로젝트: Distrotech/pine
long sm_unsubscribe (char *mailbox)
{
  FILE *f,*tf;
  char *s,tmp[MAILTMPLEN],old[MAILTMPLEN],newname[MAILTMPLEN];
  int found = NIL;
				/* canonicalize INBOX */
  if (!compare_cstring (mailbox,"INBOX")) mailbox = "INBOX";
  SUBSCRIPTIONFILE (old);	/* make file names */
  SUBSCRIPTIONTEMP (newname);
  if (!(f = fopen (old,"r")))	/* open subscription database */
    MM_LOG ("No subscriptions",ERROR);
  else if (!(tf = fopen (newname,"w"))) {
    MM_LOG ("Can't create subscription temporary file",ERROR);
    fclose (f);
  }
  else {
    while (fgets (tmp,MAILTMPLEN,f)) {
      if (s = strchr (tmp,'\n')) *s = '\0';
      if (strcmp (tmp,mailbox)) fprintf (tf,"%s\n",tmp);
      else found = T;		/* found the name */
    }
    fclose (f);
    if (fclose (tf) == EOF)
      MM_LOG ("Can't write subscription temporary file",ERROR);
    else if (!found) {
      sprintf (tmp,"Not subscribed to mailbox %.80s",mailbox);
      MM_LOG (tmp,ERROR);	/* error if at end */
    }
    else if (!unlink (old) && !rename (newname,old)) return LONGT;
    else MM_LOG ("Can't update subscription database",ERROR);
  }
  return NIL;
}
예제 #4
0
파일: smanager.c 프로젝트: Distrotech/pine
long sm_subscribe (char *mailbox)
{
  FILE *f;
  char *s,db[MAILTMPLEN],tmp[MAILTMPLEN];
				/* canonicalize INBOX */
  if (!compare_cstring (mailbox,"INBOX")) mailbox = "INBOX";
  SUBSCRIPTIONFILE (db);	/* open subscription database */
  if (f = fopen (db,"r")) {	/* make sure not already there */
    while (fgets (tmp,MAILTMPLEN,f)) {
      if (s = strchr (tmp,'\n')) *s = '\0';
      if (!strcmp (tmp,mailbox)) {/* already subscribed? */
	sprintf (tmp,"Already subscribed to mailbox %.80s",mailbox);
	MM_LOG (tmp,ERROR);
	fclose (f);
	return NIL;
      }
    }
    fclose (f);
  }
  if (!(f = fopen (db,"a"))) {	/* append new entry */
    MM_LOG ("Can't append to subscription database",ERROR);
    return NIL;
  }
  fprintf (f,"%s\n",mailbox);
  return (fclose (f) == EOF) ? NIL : T;
}
예제 #5
0
파일: netmsg.c 프로젝트: Distrotech/pine
FILE *netmsg_slurp (NETSTREAM *stream,unsigned long *size,unsigned long *hsiz)
{
  unsigned long i;
  char *s,*t,tmp[MAILTMPLEN];
  FILE *f = tmpfile ();
  if (!f) {
    sprintf (tmp,".%lx.%lx",(unsigned long) time (0),(unsigned long)getpid ());
    if (f = fopen (tmp,"wb+")) unlink (tmp);
    else {
      sprintf (tmp,"Unable to create scratch file: %.80s",strerror (errno));
      MM_LOG (tmp,ERROR);
      return NIL;
    }
  }
  *size = 0;			/* initially emtpy */
  if (hsiz) *hsiz = 0;
  while (s = net_getline (stream)) {
    if (*s == '.') {		/* possible end of text? */
      if (s[1]) t = s + 1;	/* pointer to true start of line */
      else {
	fs_give ((void **) &s);	/* free the line */
	break;			/* end of data */
      }
    }
    else t = s;			/* want the entire line */
    if (f) {			/* copy it to the file */
      i = strlen (t);		/* size of line */
      if ((fwrite (t,(size_t) 1,(size_t) i,f) == i) &&
	  (fwrite ("\015\012",(size_t) 1,(size_t) 2,f) == 2)) {
	*size += i + 2;		/* tally up size of data */
				/* note header position */
	if (!i && hsiz && !*hsiz) *hsiz = *size;
      }
      else {
	sprintf (tmp,"Error writing scratch file at byte %lu",*size);
	MM_LOG (tmp,ERROR);
	fclose (f);		/* forget it */
	f = NIL;		/* failure now */
      }
    }
    fs_give ((void **) &s);	/* free the line */
  }
				/* if making a file, rewind to start of file */
  if (f) fseek (f,(unsigned long) 0,L_SET);
				/* header consumes entire message */
  if (hsiz && !*hsiz) *hsiz = *size;
  return f;			/* return the file descriptor */
}
예제 #6
0
/** Release method of the reserve pool low-memory handler. */
static Bool mm_reserve_release(low_mem_handler_t *handler,
                               corecontext_t *context, low_mem_offer_t *offer)
{
  HQASSERT(handler != NULL, "No handler");
  HQASSERT(context != NULL, "No context");
  HQASSERT(offer != NULL, "No offer");
  HQASSERT(offer->next == NULL, "Multiple offers");
  UNUSED_PARAM(low_mem_handler_t *, handler);
  UNUSED_PARAM(corecontext_t*, context);
  UNUSED_PARAM(low_mem_offer_t*, offer);

#ifdef REGAIN_AT_FREE
  if ( !multi_mutex_trylock(&reserve_mutex) )
    return TRUE; /* give up if can't get the lock */
#endif
  /* Other threads could have reduced the reserve level since the offer,
     but this thread still needs memory, so release the current level. */
  MM_LOG(( LOG_RF, "%u 0x%08x 0x%08x",
           mm_reserve_level + 1,
           (unsigned)mm_reserve_table[mm_reserve_level].ptr,
           mm_reserve_table[mm_reserve_level].size ));
  mps_free( mm_pool_reserve,
            mm_reserve_table[mm_reserve_level].ptr,
            mm_reserve_table[mm_reserve_level].size );
  mm_reserve_table[mm_reserve_level].ptr = NULL;
  mm_reserve_level++;
  mm_memory_is_low = TRUE;
#ifdef REGAIN_AT_FREE
  multi_mutex_unlock(&reserve_mutex);
#endif
  return TRUE;
}
예제 #7
0
/** Tries to reclaim as much of the reserve as is more valuable than the
    given cost. Returns success. */
static Bool mm_reserve_get(mm_cost_t limit)
{
  mps_res_t res;

  HQASSERT( mm_reserve_level >= 0 &&
            mm_reserve_level <= mm_reserve_numlevels,
            "mm_reserve_get: mm_reserve_level is invalid" );

  while ( mm_reserve_level > 0
          && mm_cost_less_than(limit,
                               mm_reserve_table[mm_reserve_level-1].cost) ) {
    res = mps_alloc( & mm_reserve_table[mm_reserve_level - 1].ptr,
                     mm_pool_reserve,
                     (size_t)mm_reserve_table[mm_reserve_level - 1].size );
    if ( res != MPS_RES_OK )
      return FALSE;
    mm_reserve_level--;
    MM_LOG(( LOG_RG, "%u 0x%08x 0x%08x",
             mm_reserve_level + 1,
             (unsigned)mm_reserve_table[mm_reserve_level].ptr,
             mm_reserve_table[mm_reserve_level].size ));
  }
  if ( mm_reserve_level == 0 && mm_commit_limit == mm_commit_base ) {
#if defined(DEBUG_BUILD)
    if ( debug_lowmemory_count > 0 )
      --debug_lowmemory_count;
    else
#endif
      mm_memory_is_low = FALSE;
  }
  return TRUE;
}
예제 #8
0
// Called from the MediaStreamGraph thread
// this can be in response to our own RemoveListener() (via ::Remove()), or
// because the DOM GC'd the DOMLocalMediaStream/etc we're attached to.
void
GetUserMediaCallbackMediaStreamListener::NotifyRemoved(MediaStreamGraph* aGraph)
{
    {
        MutexAutoLock lock(mLock); // protect access to mRemoved
        MM_LOG(("Listener removed by DOM Destroy(), mFinished = %d", (int) mFinished));
        mRemoved = true;
    }
    if (!mFinished) {
        NotifyFinished(aGraph);
    }
}
예제 #9
0
void * nrf_calloc(uint32_t count, uint32_t size)
{
    uint8_t * buffer = NULL;
    uint32_t allocated_size = (size * count);

    MM_LOG ("[nrf_calloc]: Requested size %d, count %d\r\n", allocated_size, count);

    uint32_t retval = nrf_mem_reserve(&buffer,&allocated_size);
    if (retval == NRF_SUCCESS)
    {
        MM_LOG ("[nrf_calloc]: buffer %p, total size %d\r\n", buffer, allocated_size);
        memset(buffer,0, allocated_size);
    }
    else
    {
        MM_LOG("[nrf_calloc]: Failed to allocate memory %d\r\n", allocated_size);
        buffer = NULL;
    }

    return buffer;
}
예제 #10
0
/** Shared release method of the commit extension low-memory handlers. */
static Bool mm_commit_release(low_mem_handler_t *handler,
                              corecontext_t *context, low_mem_offer_t *offer)
{
  mm_commit_extension_t *extension = (mm_commit_extension_t *)handler;
  size_t limit;
  mps_res_t res;

  HQASSERT(handler != NULL, "No handler");
  HQASSERT(context != NULL, "No context");
  HQASSERT(offer != NULL, "No offer");
  HQASSERT(offer->next == NULL, "Multiple offers");
  UNUSED_PARAM(corecontext_t*, context);

#ifdef REGAIN_AT_FREE
  if ( !multi_mutex_trylock(&reserve_mutex) )
    return TRUE; /* give up if can't get the lock */
  /* Other threads might have reduced the commit limit since the offer,
     but this thread still needs the same amount memory as before. */
#endif
  HQASSERT(mm_commit_limit == mps_arena_commit_limit(mm_arena),
           "mm_commit_limit out of synch with MPS");
  HQASSERT(mm_commit_limit < extension->limit,
           "Commit limit raised unexpectedly.");
  limit = min(mm_commit_limit + max(offer->taken_size, extension->delta),
              extension->limit);
  res = mps_arena_commit_limit_set(mm_arena, limit);
  HQASSERT(res == MPS_RES_OK, "Failed to set commit limit");
  mm_commit_limit = limit;
  mm_memory_is_low = TRUE;
  MM_LOG(( LOG_CX, "0x%08x", mm_commit_limit ));
#if defined( DEBUG_BUILD )
  { /* If extending without limit, warn the user. */
    mm_commit_extension_t *extension =
      limit <= mm_arena_extension.limit ? &mm_arena_extension : &mm_use_all;

    if ( !extension->reported ) {
      if ( extension != &mm_arena_extension )
        monitorf((uint8 *)"Warning: using all available memory\n");
      extension->reported = TRUE;
    }
  }
#endif
#ifdef REGAIN_AT_FREE
  multi_mutex_unlock(&reserve_mutex);
#endif
  return TRUE;
}
예제 #11
0
long dummy_canonicalize (char *tmp,char *ref,char *pat)
{
  unsigned long i;
  char *s,dev[4];
				/* initially no device */
  dev[0] = dev[1] = dev[2] = dev[3] = '\0';
  if (ref) switch (*ref) {	/* preliminary reference check */
  case '{':			/* remote names not allowed */
    return NIL;			/* disallowed */
  case '\0':			/* empty reference string */
    break;
  default:			/* all other names */
    if (ref[1] == ':') {	/* start with device name? */
      dev[0] = *ref++; dev[1] = *ref++;
    }
    break;
  }
  if (pat[1] == ':') {		/* device name in pattern? */
    dev[0] = *pat++; dev[1] = *pat++;
    ref = NIL;			/* ignore reference */
  }
  switch (*pat) {
  case '#':			/* namespace names */
    if (mailboxfile (tmp,pat)) strcpy (tmp,pat);
    else return NIL;		/* unknown namespace */
    break;
  case '{':			/* remote names not allowed */
    return NIL;
  case '\\':			/* rooted name */
    ref = NIL;			/* ignore reference */
    break;
  }
				/* make sure device names are rooted */
  if (dev[0] && (*(ref ? ref : pat) != '\\')) dev[2] = '\\';
				/* build name */
  sprintf (tmp,"%s%s%s",dev,ref ? ref : "",pat);
  ucase (tmp);			/* force upper case */
				/* count wildcards */
  for (i = 0, s = tmp; *s; *s++) if ((*s == '*') || (*s == '%')) ++i;
  if (i > MAXWILDCARDS) {	/* ridiculous wildcarding? */
    MM_LOG ("Excessive wildcards in LIST/LSUB",ERROR);
    return NIL;
  }
  return T;
}
예제 #12
0
void mm_reserve_destroy(void)
{
  unsigned level;

  if ( mm_pool_reserve != NULL ) {
    low_mem_handler_deregister(&reserve_pool_handler);
    mps_pool_destroy(mm_pool_reserve);
#ifdef REGAIN_AT_FREE
    multi_mutex_finish(&reserve_mutex);
#endif
  }
  mm_pool_reserve = NULL;
  for ( level = mm_reserve_level ; level < mm_reserve_numlevels ; level++ ) {
    mm_reserve_table[level].ptr = NULL;
    MM_LOG((LOG_RF, "%u 0x%08x", level + 1, mm_reserve_table[level].size));
  }
  mm_reserve_level = 0; /* Don't try to regain */
}
예제 #13
0
/** \brief Reduce the commit limit as far as possible within the
    extension, but only down to the cost given.

  Callers must shrink in the right order, so this will not be called when the
  commit limit is above the range of this extension, unless the cost limit is
  above it as well (this simplifies the callers).
 */
static Bool mm_shrink(mm_commit_extension_t *extension, mm_cost_t cost_limit)
{
  size_t curr_limit;
  Bool enough = TRUE;

  curr_limit = mm_commit_limit;
  HQASSERT(curr_limit == mps_arena_commit_limit( mm_arena ),
           "mm_commit_limit out of synch with MPS");
  HQASSERT(mm_commit_limit >= mm_arena_extension.base
           && mm_commit_limit <= mm_use_all.limit,
           "mm_commit_limit out of range");

  if ( !mm_cost_less_than(cost_limit, extension->cost) )
    return TRUE;

  HQASSERT(curr_limit <= extension->limit,
           "Shrinking using the wrong extension.");
  while ( curr_limit > extension->base ) {
    size_t trylimit;

    /* Now reduce the current limit, capping at the base for this level */
    trylimit = curr_limit - extension->delta;
    if ( trylimit > curr_limit /* wrap around */ || trylimit < extension->base )
      trylimit = extension->base;
    /* Try to set the new limit */
    if ( mps_arena_commit_limit_set( mm_arena, trylimit ) != MPS_RES_OK ) {
      enough = FALSE; break; /* still holding too much memory! */
    }
    curr_limit = trylimit;
  }
  if ( curr_limit != mm_commit_limit ) {
    mm_commit_limit = curr_limit;
    MM_LOG(( LOG_CS, "0x%08x", mm_commit_limit ));
    HQASSERT(mm_reserve_level == 0,
             "Shouldn't get here while using the reserve pool.");
    if ( mm_commit_limit == mm_commit_base )
      mm_memory_is_low = FALSE;
  }
  return enough;
}
예제 #14
0
파일: news.c 프로젝트: Distrotech/imap
long news_canonicalize (char *ref,char *pat,char *pattern)
{
  unsigned long i;
  char *s;
  if (ref && *ref) {		/* have a reference */
    strcpy (pattern,ref);	/* copy reference to pattern */
				/* # overrides mailbox field in reference */
    if (*pat == '#') strcpy (pattern,pat);
				/* pattern starts, reference ends, with . */
    else if ((*pat == '.') && (pattern[strlen (pattern) - 1] == '.'))
      strcat (pattern,pat + 1);	/* append, omitting one of the period */
    else strcat (pattern,pat);	/* anything else is just appended */
  }
  else strcpy (pattern,pat);	/* just have basic name */
  if ((pattern[0] == '#') && (pattern[1] == 'n') && (pattern[2] == 'e') &&
      (pattern[3] == 'w') && (pattern[4] == 's') && (pattern[5] == '.') &&
      !strchr (pattern,'/')) {	/* count wildcards */
    for (i = 0, s = pattern; *s; *s++) if ((*s == '*') || (*s == '%')) ++i;
				/* success if not too many */
    if (i <= MAXWILDCARDS) return LONGT;
    MM_LOG ("Excessive wildcards in LIST/LSUB",ERROR);
  }
  return NIL;
}
예제 #15
0
Bool mm_extension_init(size_t addr_space_size,
                       size_t working_size, size_t extension_size,
                       Bool use_all_mem)
{
  size_t extended_commit_limit;
  Bool res;

  MM_LOG(( LOG_IP, "0x%08x 0x%08x 0x%08x 0x%08x %d",
           (unsigned)mm_arena,
           addr_space_size, working_size, extension_size,
           (int)use_all_mem ));

  if ( working_size + extension_size < working_size ) /* overflow? */
    extended_commit_limit = (size_t)-1;
  else
    extended_commit_limit = working_size + extension_size;
  if ( addr_space_size < extended_commit_limit )
    return FALSE; /* a configuration error in the skin */
  mm_commit_base = working_size;

  /* Extension beyond working_size, into arena extension, to reduce partial
   * paints. */

  /* Always init, so it all works when the extension is configured off. */
  mm_arena_extension.base = mm_arena_extension.limit = working_size;
  mm_arena_extension.cost = mm_cost_none;

  if ( extension_size > 0 ) {
    mm_arena_extension.limit = extended_commit_limit;
    mm_arena_extension.delta = 256*1024; /* guess */
    mm_arena_extension.cost.tier = memory_tier_partial_paint;
    mm_arena_extension.cost.value = 0.1f;
    HQASSERT(mm_cost_less_than(mm_arena_extension.cost, mm_cost_normal),
             "Default cost doesn't include arena extension.");
    HQASSERT(mm_cost_less_than(mm_cost_below_reserves, mm_arena_extension.cost),
             "mm_cost_below_reserves includes arena extension.");

    res = low_mem_handler_register(&mm_arena_extension.handler);
    if ( !res )
      return FALSE;
  }

  /* Extension beyond arena extension, intended to be permitted only after
   * a partial paint has been attempted (or is not allowed). */

  /* Always init, so it all works when the extension is configured off. */
  mm_use_all.base = mm_use_all.limit = mm_arena_extension.limit;
  mm_use_all.cost = mm_cost_none;

  if ( use_all_mem ) {
    if ( addr_space_size > mm_arena_extension.limit ) {
      mm_use_all.limit = addr_space_size;
      mm_use_all.delta = 256*1024; /* guess */
      mm_use_all.cost.tier = memory_tier_trash_vm;
      mm_use_all.cost.value = 1.0f;
      HQASSERT(mm_cost_less_than(mm_use_all.cost, mm_cost_normal),
               "Default cost doesn't include use-all extension.");
      HQASSERT(mm_cost_less_than(mm_cost_below_reserves, mm_use_all.cost),
               "mm_cost_below_reserves includes use-all extension.");

      res = low_mem_handler_register(&mm_use_all.handler);
      if ( !res )
        return FALSE;
    }
  }

  /* Now set the current commit limit */
  mm_commit_limit = working_size;
  if ( mps_arena_commit_limit_set( mm_arena, mm_commit_limit ) != MPS_RES_OK )
    return FALSE;

  /* Try to hang onto a few a spare segments. Note that we just use a small
   * and fairly arbitrary number here. It's small 'cos there are few pools
   * which exhibit the problem of repeated allocs and frees that cause
   * segments to be created and destroyed (examples: dl pool, and to a much
   * lesser extent, color pool - as it overflows onto a second segment). */
  mps_arena_spare_commit_limit_set( mm_arena, (size_t)4 * 64 * 1024 );
  return TRUE;
}
예제 #16
0
SEARCHPGM *prune_criteria (char *criteria)
{
  SEARCHPGM *pgm = NIL;
  char *criterion,*r,tmp[MAILTMPLEN];
  int f;
  if (criteria) {		/* only if criteria defined */
				/* make writeable copy of criteria */
    criteria = cpystr (criteria);
				/* for each criterion */
    for (pgm = mail_newsearchpgm (), criterion = strtok_r (criteria," ",&r);
	 criterion; (criterion = strtok_r (NIL," ",&r))) {
      f = NIL;			/* init then scan the criterion */
      switch (*ucase (criterion)) {
      case 'A':			/* possible ALL, ANSWERED */
	if (!strcmp (criterion+1,"LL")) f = T;
	else if (!strcmp (criterion+1,"NSWERED")) f = pgm->answered = T;
	break;
      case 'B':			/* possible BCC, BEFORE, BODY */
	if (!strcmp (criterion+1,"CC"))
	  f = mail_criteria_string (&pgm->bcc,&r);
	else if (!strcmp (criterion+1,"EFORE"))
	  f = mail_criteria_date (&pgm->before,&r);
	else if (!strcmp (criterion+1,"ODY"))
	  f = mail_criteria_string (&pgm->body,&r);
	break;
      case 'C':			/* possible CC */
	if (!strcmp (criterion+1,"C")) f = mail_criteria_string (&pgm->cc,&r);
	break;
      case 'D':			/* possible DELETED, DRAFT */
	if (!strcmp (criterion+1,"ELETED")) f = pgm->deleted = T;
	else if (!strcmp (criterion+1,"RAFT")) f = pgm->draft = T;
	break;
      case 'F':			/* possible FLAGGED, FROM */
	if (!strcmp (criterion+1,"LAGGED")) f = pgm->flagged = T;
	else if (!strcmp (criterion+1,"ROM"))
	  f = mail_criteria_string (&pgm->from,&r);
	break;
      case 'K':			/* possible KEYWORD */
	if (!strcmp (criterion+1,"EYWORD"))
	  f = mail_criteria_string (&pgm->keyword,&r);
	break;
      case 'L':			/* possible LARGER */
	if (!strcmp (criterion+1,"ARGER"))
	  f = prune_criteria_number (&pgm->larger,&r);

      case 'N':			/* possible NEW */
	if (!strcmp (criterion+1,"EW")) f = pgm->recent = pgm->unseen = T;
	break;
      case 'O':			/* possible OLD, ON */
	if (!strcmp (criterion+1,"LD")) f = pgm->old = T;
	else if (!strcmp (criterion+1,"N"))
	  f = mail_criteria_date (&pgm->on,&r);
	break;
      case 'R':			/* possible RECENT */
	if (!strcmp (criterion+1,"ECENT")) f = pgm->recent = T;
	break;
      case 'S':			/* possible SEEN, SENT*, SINCE, SMALLER,
				   SUBJECT */
	if (!strcmp (criterion+1,"EEN")) f = pgm->seen = T;
	else if (!strncmp (criterion+1,"ENT",3)) {
	  if (!strcmp (criterion+4,"BEFORE"))
	    f = mail_criteria_date (&pgm->sentbefore,&r);
	  else if (!strcmp (criterion+4,"ON"))
	    f = mail_criteria_date (&pgm->senton,&r);
	  else if (!strcmp (criterion+4,"SINCE"))
	    f = mail_criteria_date (&pgm->sentsince,&r);
	}
	else if (!strcmp (criterion+1,"INCE"))
	  f = mail_criteria_date (&pgm->since,&r);
	else if (!strcmp (criterion+1,"MALLER"))
	  f = prune_criteria_number (&pgm->smaller,&r);
	else if (!strcmp (criterion+1,"UBJECT"))
	  f = mail_criteria_string (&pgm->subject,&r);
	break;
      case 'T':			/* possible TEXT, TO */
	if (!strcmp (criterion+1,"EXT"))
	  f = mail_criteria_string (&pgm->text,&r);
	else if (!strcmp (criterion+1,"O"))
	  f = mail_criteria_string (&pgm->to,&r);
	break;
      case 'U':			/* possible UN* */
	if (criterion[1] == 'N') {
	  if (!strcmp (criterion+2,"ANSWERED")) f = pgm->unanswered = T;
	  else if (!strcmp (criterion+2,"DELETED")) f = pgm->undeleted = T;
	  else if (!strcmp (criterion+2,"DRAFT")) f = pgm->undraft = T;
	  else if (!strcmp (criterion+2,"FLAGGED")) f = pgm->unflagged = T;
	  else if (!strcmp (criterion+2,"KEYWORD"))
	    f = mail_criteria_string (&pgm->unkeyword,&r);
	  else if (!strcmp (criterion+2,"SEEN")) f = pgm->unseen = T;
	}
	break;
      default:			/* we will barf below */
	break;
      }

      if (!f) {			/* if can't identify criterion */
	sprintf (tmp,"Unknown search criterion: %.30s",criterion);
	MM_LOG (tmp,ERROR);
	mail_free_searchpgm (&pgm);
	break;
      }
    }
				/* no longer need copy of criteria */
    fs_give ((void **) &criteria);
  }
  return pgm;
}
예제 #17
0
uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(pp_buffer);
    NULL_PARAM_CHECK(p_size);

    const uint32_t requested_size = (*p_size);

    VERIFY_REQUESTED_SIZE(requested_size);

    MM_LOG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size);

    MM_MUTEX_LOCK();

    const uint32_t block_cat    = get_block_cat(requested_size, TOTAL_BLOCK_COUNT);
    uint32_t       block_index  = m_block_start[block_cat];
    uint32_t       memory_index = m_block_mem_start[block_cat];
    uint32_t       err_code     = (NRF_ERROR_NO_MEM | MEMORY_MANAGER_ERR_BASE);

    MM_LOG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n",
           block_index,
           TOTAL_BLOCK_COUNT);

    for (; block_index < TOTAL_BLOCK_COUNT; block_index++)
    {
        uint32_t block_size = get_block_size(block_index);

        if (is_block_free(block_index) == true)
        {
            MM_LOG("[MM]: Reserving block 0x%08lX\r\n", block_index);

            // Search succeeded, found free block.
            err_code     = NRF_SUCCESS;

            // Allocate block.
            block_allocate(block_index);

            (*pp_buffer) = &m_memory[memory_index];
            (*p_size)    = block_size;

#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
            (*p_min_size) = MIN((*p_min_size), requested_size);
            (*p_max_size) = MAX((*p_max_size), requested_size);
#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS

            break;
        }
        memory_index += block_size;
    }
    if (err_code != NRF_SUCCESS)
    {
        MM_LOG ("[MM]: Memory reservation result %d, memory %p, size %d!",
                err_code,
                (*pp_buffer),
                (*p_size));

#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
        nrf_mem_diagnose();
#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
    }

    MM_MUTEX_UNLOCK();

    MM_LOG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n", (*pp_buffer), err_code);

    return err_code;
}