Exemple #1
0
mv_sem_t *mv_semaphore_create(S32 count) {
  mv_sem_t *sem;

  NX_ASSERT(count >= 0);

  sem = nx_calloc(1, sizeof(*sem));
  sem->count = count;
  mv_list_init(sem->blocked_tasks);

  return sem;
}
Exemple #2
0
/* Build a new task descriptor for a task that will run the given
 * function when activated.
 */
static mv_task_t *new_task(nx_closure_t func, U32 stack_size) {
  mv_task_t *t;
  nx_task_stack_t *s;

  NX_ASSERT_MSG((stack_size & 0x3) == 0, "Stack must be\n4-byte aligned");

  t = nx_calloc(1, sizeof(*t));
  t->stack_base = nx_calloc(1, stack_size);
  t->stack_current = (U32*) ((U32)t->stack_base + stack_size - sizeof(*s));
  s = (nx_task_stack_t*)t->stack_current;
  s->pc = (U32) func;
  s->lr = (U32) task_shutdown;
  s->cpsr = MODE_SYS;
  if (s->pc & 0x1) {
    s->pc &= 0xFFFFFFFE;
    s->cpsr |= 0x20;
  }
  t->state = READY;

  mv_list_init_singleton(t, t);

  return t;
}
Exemple #3
0
void mv__scheduler_task_suspend(U32 time) {
  struct mv_alarm_entry *a;
  mv_scheduler_lock();
  NX_ASSERT(sched_state.task_current->state == READY);

  /* Prepare the alarm descriptor. */
  a = nx_calloc(1, sizeof(*a));
  a->wakeup_time = nx_systick_get_ms() + time;
  a->task = sched_state.task_current;

  mv__scheduler_task_block();

  /* If the alarm list is empty, the initialization is
   * trivial. Otherwise, we need to locate the correct place in the list
   * for a sorted insertion.
   */
  if (mv_list_is_empty(sched_state.alarms_pending)) {
    mv_list_init_singleton(sched_state.alarms_pending, a);
  } else if (a->wakeup_time <= sched_state.alarms_pending->wakeup_time) {
    mv_list_add_head(sched_state.alarms_pending, a);
  } else if (a->wakeup_time >= sched_state.alarms_pending->prev->wakeup_time) {
    mv_list_add_tail(sched_state.alarms_pending, a);
  } else {
    struct mv_alarm_entry *ptr = sched_state.alarms_pending;

    while(ptr->next->wakeup_time < a->wakeup_time)
      ptr = ptr->next;

    mv_list_insert_after(ptr, a);
  }

  /* The alarm is programmed and the task configured to block. It will
   * be preempted when the scheduler completely unlocks.
   */
  mv_scheduler_unlock();
}
Exemple #4
0
nxweb_result nxweb_cache_store_response(nxweb_http_server_connection* conn, nxweb_http_response* resp) {
  nxe_time_t loop_time=nxweb_get_loop_time(conn);
  if (!resp->status_code) resp->status_code=200;

  if (resp->status_code==200 && resp->sendfile_path // only cache content from files
      && resp->content_length>=0 && resp->content_length<=NXWEB_MAX_CACHED_ITEM_SIZE // must be small
      && resp->sendfile_offset==0 && resp->sendfile_end==resp->content_length // whole file only
      && resp->sendfile_end>=resp->sendfile_info.st_size // st_size could be zero if not initialized
      && alignhash_size(_nxweb_cache)<NXWEB_MAX_CACHED_ITEMS+16) {

    const char* fpath=resp->sendfile_path;
    const char* key=resp->cache_key;
    if (nxweb_cache_try(conn, resp, key, 0, resp->last_modified)!=NXWEB_MISS) return NXWEB_OK;

    nxweb_cache_rec* rec=nx_calloc(sizeof(nxweb_cache_rec)+resp->content_length+1+strlen(key)+1);

    rec->expires_time=loop_time+NXWEB_DEFAULT_CACHED_TIME;
    rec->last_modified=resp->last_modified;
    rec->content_type=resp->content_type;       // assume content_type and content_charset come
    rec->content_charset=resp->content_charset; // from statically allocated memory, which won't go away
    rec->content_length=resp->content_length;
    rec->gzip_encoded=resp->gzip_encoded;
    char* ptr=((char*)rec)+offsetof(nxweb_cache_rec, content);
    int fd;
    if ((fd=open(fpath, O_RDONLY))<0 || read(fd, ptr, resp->content_length)!=resp->content_length) {
      if (fd>0) close(fd);
      nx_free(rec);
      nxweb_log_error("nxweb_cache_file_store_and_send(): [%s] stat() was OK, but open/read() failed", fpath);
      nxweb_send_http_error(resp, 500, "Internal Server Error");
      return NXWEB_ERROR;
    }
    close(fd);
    resp->content=ptr;
    ptr+=resp->content_length;
    *ptr++='\0';
    strcpy(ptr, key);
    key=ptr;

    int ret=0;
    ah_iter_t ci;
    pthread_mutex_lock(&_nxweb_cache_mutex);
    ci=alignhash_set(nxweb_cache, _nxweb_cache, key, &ret);
    if (ci!=alignhash_end(_nxweb_cache)) {
      if (ret!=AH_INS_ERR) {
        alignhash_value(_nxweb_cache, ci)=rec;
        cache_rec_link(rec);
        rec->ref_count++;
        cache_check_size();
        pthread_mutex_unlock(&_nxweb_cache_mutex);
        nxweb_log_info("memcached %s", key);
        conn->hsp.req_data=rec;
        assert(!conn->hsp.req_finalize);
        conn->hsp.req_finalize=cache_rec_unref;
        //nxweb_start_sending_response(conn, resp);
        return NXWEB_OK;
      }
      else { // AH_INS_ERR => key already exists (added by other thread)
        nx_free(rec);
        rec=alignhash_value(_nxweb_cache, ci);
        resp->content_length=rec->content_length;
        resp->content=rec->content;
        resp->content_type=rec->content_type;
        resp->content_charset=rec->content_charset;
        resp->last_modified=rec->last_modified;
        resp->gzip_encoded=rec->gzip_encoded;
        rec->ref_count++;
        pthread_mutex_unlock(&_nxweb_cache_mutex);
        conn->hsp.req_data=rec;
        assert(!conn->hsp.req_finalize);
        conn->hsp.req_finalize=cache_rec_unref;
        //nxweb_start_sending_response(conn, resp);
        return NXWEB_OK;
      }
    }
    pthread_mutex_unlock(&_nxweb_cache_mutex);
    nx_free(rec);
  }
  return NXWEB_OK;
}
Exemple #5
0
static struct sem_task_handle *make_sem_task_handle(mv_task_t *task) {
  struct sem_task_handle *h = nx_calloc(1, sizeof(*h));
  h->task = task;
  return h;
}