示例#1
0
void *
philosopher (void *num)
{
  int id;
  int left_fork, right_fork, f;

  id = (int)num;
  printf ("Philosopher %d sitting down to dinner.\n", id);
  right_fork = id;
  left_fork = id + 1;
 
  /* Wrap around the forks - somewhat more complicated */
  if (left_fork == PHILO) {
    left_fork = right_fork;
    right_fork=0;
  }
 
  while (f = food_on_table ()) {

    printf ("Philosopher %d: get dish %d.\n", id, f);
    get_fork (id, right_fork, "right");
    get_fork (id, left_fork, "left");

    printf ("Philosopher %d: eating.\n", id);
    usleep (DELAY * (FOOD - f + 1));
    down_forks (left_fork, right_fork);
  }
  printf ("Philosopher %d is done eating.\n", id);
  return (NULL);
}
示例#2
0
文件: fork.c 项目: hsaransa/std2
request* std2_new_request(int fork_id, int mod, int func)
{
    fork_state* fs = get_fork(fork_id);

    /* Make request and add it to list. */

    request* req = malloc(sizeof(request));
    memset(req, 0, sizeof(request));

    req->fork_id = fork_id;
    req->id = fs->next_id++;
    req->next = fs->first_request;
    fs->first_request = req;

    /* Output request header. */

    buffer_append_32(&fs->out_buffer, 'c');
    buffer_append_32(&fs->out_buffer, req->id);
    buffer_append_32(&fs->out_buffer, mod);
    buffer_append_32(&fs->out_buffer, func);

    yield_callbacks(fork_id);

    return req;
}
示例#3
0
文件: fork.c 项目: hsaransa/std2
static void yield_callbacks(int fork_id)
{
    fork_state* fs = get_fork(fork_id);

    if (!fs->has_yielded_reader)
    {
        struct std2_callback cb;
        cb.flags = STD2_CALLBACK_READ | STD2_CALLBACK_ERROR | STD2_CALLBACK_ABORT;
        cb.fd    = fs->to_host_fd[0];
        cb.user  = (void*)fork_id;
        cb.func  = read_cb;
        std2_yield_callback(&cb);

        fs->has_yielded_reader = 1;
    }

    if (!fs->has_yielded_writer && fs->out_buffer.pos < fs->out_buffer.size)
    {
        struct std2_callback cb;
        cb.flags = STD2_CALLBACK_WRITE | STD2_CALLBACK_ABORT;
        cb.fd    = fs->to_client_fd[1];
        cb.user  = (void*)fork_id;
        cb.func  = write_cb;
        std2_yield_callback(&cb);

        fs->has_yielded_writer = 1;
    }
}
示例#4
0
文件: fork.c 项目: hsaransa/std2
static void write_cb(int fd, int mask, void* user)
{
    int fork_id = (int)user;
    fork_state* fs = get_fork(fork_id);

    fs->has_yielded_writer = 0;

    if (mask & STD2_CALLBACK_ABORT)
    {
        assert(!"abort not implemented");
        abort();
        return;
    }

    int r = write_buffer(fd, &fs->out_buffer);
    if (r < 0)
    {
        // TODO: abort requests and stuff
        fprintf(stderr, "std2: write error: %s\n", strerror(errno));
        abort();
    }

    buffer_compact(&fs->out_buffer);

    yield_callbacks(fork_id);
}
示例#5
0
文件: fork.c 项目: hsaransa/std2
static void return_func(int id, void* ret, void* arg0, void* arg1)
{
    (void)arg0;

    request* req = arg1;
    fork_state* fs = get_fork(req->fork_id);

    int ret_id   = buffer_read_32(&fs->in_buffer);
    int ret_size = buffer_read_32(&fs->in_buffer);
    buffer_compact(&fs->in_buffer);

    assert(req->id == ret_id);
    assert(req->return_id == id);

    char* p      = buffer_cursor(&fs->in_buffer);
    char* start = p;

    switch (req->ret_type.type)
    {
    case STD2_VOID:
        break;

    case STD2_INT32:
        *(std2_int32*)ret = *(std2_int32*)p;
        p += 4;
        break;

    case STD2_C_STRING:
        {
            int size = *(int*)p;
            p += 4;
            *(const char**)ret = p;
            p += size;
        }
        break;

    case STD2_INSTANCE:
        *(void**)ret = *(void**)p;
        p += sizeof(void*);
        break;

    default:
        fprintf(stderr, "std2: todo return type %d\n", req->ret_type.type);
        abort();
    }

    assert(p - start == ret_size);

    fs->in_buffer.pos += ret_size;

    fs->return_processed = 1;

    request** prev = &fs->first_request;
    while (*prev != req && *prev)
        prev = &(*prev)->next;
    assert(*prev);
    *prev = (*prev)->next;
    free(req);
}
示例#6
0
文件: fork.c 项目: hsaransa/std2
static void read_cb(int fd, int mask, void* user)
{
    int fork_id = (int)user;
    fork_state* fs = get_fork(fork_id);
    assert(fd == fs->to_host_fd[0]);

    fs->has_yielded_reader = 0;

    if (mask & STD2_CALLBACK_ABORT)
    {
        assert(!"abort not implemented");
        abort();
        return;
    }

    buffer_reserve(&fs->in_buffer, 1024);
    int closed = read_buffer_append(fd, &fs->in_buffer, 1);

    /* If fd was closed, abort all returns. */

    if (closed)
    {
        request* req;
        for (req = fs->first_request; req; req = req->next)
            std2_abort_return(req->return_id);
        return;
    }

    /* fd wasn't closed so yield new read callback. */
    yield_callbacks(fork_id);

    if (!fs->return_processed)
        return;

    fprintf(stderr, "NAH\n");

    if (buffer_avail(&fs->in_buffer) < 8)
        return;

    int ret_id   = *(std2_int32*)buffer_cursor(&fs->in_buffer);
    int ret_size = *((std2_int32*)buffer_cursor(&fs->in_buffer) + 1);

    if (buffer_avail(&fs->in_buffer) < 8 + ret_size)
        return;

    fprintf(stderr, "std2: got return from fork, id %d, size %d\n", ret_id, ret_size);
    request* req;
    for (req = fs->first_request; req; req = req->next)
        if (req->id == ret_id)
        {
            fs->return_processed = 0;
            std2_continue_return(req->return_id, return_func, req);
            return;
        }

    fprintf(stderr, "std2: bad request id\n");
}
示例#7
0
文件: fork.c 项目: hsaransa/std2
void std2_new_unrefer_request(int fork_id, int mod, int clas, void* ptr)
{
    fork_state* fs = get_fork(fork_id);

    buffer_append_32(&fs->out_buffer, 'u');
    buffer_append_32(&fs->out_buffer, 0);
    buffer_append_32(&fs->out_buffer, mod);
    buffer_append_32(&fs->out_buffer, clas);
    buffer_append_data(&fs->out_buffer, &ptr, sizeof(void*));

    yield_callbacks(fork_id);
}
示例#8
0
文件: fork.c 项目: hsaransa/std2
void std2_process_request()
{
    fork_state* fs = get_fork(current_fork_id);

    if (read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, 20))
    {
        fprintf(stderr, "std2: child got disconnection\n");
        exit(1);
    }

    int marker = buffer_read_32(&fs->in_buffer);
    int req_id = buffer_read_32(&fs->in_buffer);

    if (marker == 'c')
    {
        int m = buffer_read_32(&fs->in_buffer);
        int f = buffer_read_32(&fs->in_buffer);
        int params_size = buffer_read_32(&fs->in_buffer);

        read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, params_size);

        fprintf(stderr, "call id=%d, %d, %d, %d\n", req_id, m, f, params_size);

        // Construct parameters.

        void* start_ptr = buffer_cursor(&fs->in_buffer);
        void* end_ptr = (char*)buffer_cursor(&fs->in_buffer) + params_size;
        void* p = start_ptr;

        void* args[16];

        int param_count = std2_get_param_count(m, f);
        int i;
        for (i = 0; i < param_count; i++)
        {
            struct std2_param t = std2_get_param_type(m, f, i);
            switch (t.type)
            {
                case STD2_INT32:
                    args[i] = p;
                    p = (char*)p + 4;
                    break;

                case STD2_C_STRING:
                    {
                        int size = *(int*)p;
                        p = (char*)p + 4;
                        args[i] = p;
                        p = (char*)p + size;
                    }
                    break;

                case STD2_INSTANCE:
                    args[i] = *(void**)p;
                    p = (char*)p + sizeof(void*);
                    break;

                default:
                    fprintf(stderr, "std2: (c) unknown type %d\n", t.type);
                    abort();
            }

            assert(p <= end_ptr);
        }

        fs->in_buffer.pos += (char*)p - (char*)start_ptr;

        // Do the call.

        struct std2_param ret_type = std2_get_return_type(m, f);

        buffer_append_32(&fs->out_buffer, req_id); // size will be filled afterwards

        int size_pos = fs->out_buffer.size;
        buffer_append_32(&fs->out_buffer, 0); // size will be filled afterwards

        int ret;

        switch (ret_type.type)
        {
            case STD2_VOID:
                ret = std2_call(0, m, f, 0, args);
                break;

            case STD2_INT32:
                {
                    std2_int32 v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                        buffer_append_32(&fs->out_buffer, v);
                }
                break;

            case STD2_C_STRING:
                {
                    const char* v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                    {
                        int l = strlen(v) + 1;
                        int n = (l + 3) & ~3;
                        buffer_append_32(&fs->out_buffer, n);
                        buffer_append_data(&fs->out_buffer, v, l);
                        buffer_append_alignment(&fs->out_buffer, 4);
                    }
                }
                break;

            case STD2_INSTANCE:
                {
                    void* v;
                    ret = std2_call(0, m, f, &v, args);
                    if (!ret)
                        buffer_append_data(&fs->out_buffer, &v, sizeof(void*));
                }
                break;

            default:
                fprintf(stderr, "std2: (a) unknown type %d\n", ret_type.type);
                abort();
        }

        if (ret)
        {
            fprintf(stderr, "delayed return\n");
            fs->out_buffer.size -= 8; // req_id and size
            return;
        }

        *(int*)((char*)fs->out_buffer.data + size_pos) =
            fs->out_buffer.size - size_pos - 4;

        while (buffer_avail(&fs->out_buffer))
            write_buffer(fs->to_host_fd[1], &fs->out_buffer);

        fprintf(stderr, "response written\n");

        buffer_compact(&fs->in_buffer);
        buffer_compact(&fs->out_buffer);
    }
    else if (marker == 'u')
    {
        assert(!"todo unrefer");
    }
    else
    {
        fprintf(stderr, "std2: protocol error, bad marker %d\n", marker);
        abort();
    }
}