Пример #1
0
int
hash_new( long capacity, hash ** hh ) {
  hash *h;
  int err;
  long s;

  INST_INIT(  );
  INST_I( new );

  if ( capacity <= 0 ) {
    capacity = 1;
  }

  if ( h = malloc( sizeof( hash ) ), !h ) {
    return ERR_Not_Enough_Memory;
  }

  if ( h->slot = malloc( sizeof( hash_slot * ) * capacity ), !h->slot ) {
    free( h );
    return ERR_Not_Enough_Memory;
  }

  h->cap = capacity;
  h->state = 0;
  h->size = 0;
  h->deleted = 0;

  h->cbd = NULL;
  h->cb_add = NULL;
  h->cb_del = NULL;
  h->cb_upd = NULL;

  for ( s = 0; s < h->cap; s++ ) {
    h->slot[s] = -1;
  }

  if ( err = buffer_init( &h->buf, 0, 256 ), ERR_None == err ) {
    *hh = h;
  }

  return err;
}
int client_main(void)
{
    int fd, r, n, m, wait = 0, retries,pid;
    void *binder, *cookie;
    bcmd_txn_t *txn;
    bwr_t bwr;
    inst_buf_t *inst, *inst_reply;
    inst_entry_t *entry, copy;
    unsigned char rbuf[RBUF_SIZE], *ibuf, *p;
    struct timeval ref, delta;
    char labels[INST_MAX_ENTRIES][8];
    unsigned long long total_usecs[INST_MAX_ENTRIES];
    unsigned long long min[INST_MAX_ENTRIES],max[INST_MAX_ENTRIES],record[INST_MAX_ENTRIES];
    FILE *fp;

    if (!share_cpus) {
        cpu_set_t cpuset;

        CPU_ZERO(&cpuset);
        CPU_SET(id + 1, &cpuset);
        r = sched_setaffinity(0, sizeof(cpuset), &cpuset);
        if (!r)
            printf("client %d is bound to CPU %d\n", id, id + 1);
        else
            fprintf(stderr, "client %d failed to be bound to CPU %d\n", id, id + 1);
    }

    fd = open("/dev/binder", O_RDWR);
    if (fd < 0) {
        fprintf(stderr, "client %d failed to open binder device\n", id);
        return -1;
    }

#if (!defined(INLINE_TRANSACTION_DATA))
    if (mmap(NULL, 128 * 1024, PROT_READ, MAP_PRIVATE, fd, 0) == MAP_FAILED) {
        fprintf(stderr, "server failed to mmap shared buffer\n");
        return -1;
    }
#endif

    while (1) {
        r = lookup_service(fd, service, sizeof(service) / 2, &binder, &cookie);
        if (r < 0) {
            fprintf(stderr, "client %d failed to find the instrumentation service\n", id);
            return -1;
        } else if (r > 0)
            break;

        if (wait++ > 1)
            fprintf(stderr, "client %d still waiting on instrumentation service to be ready\n", id);
        sleep(1);
    }
    printf("client %d found instrumentation service\n", id);

    txn = create_transaction(0, binder, cookie, 0, NULL, sizeof(inst_buf_t) + data_SZ, NULL, 0);
    if (!txn) {
        fprintf(stderr, "client %d failed to prepare transaction buffer\n", id);
        return -1;
    }

    bwr.write_buffer = (unsigned long)txn;
    bwr.read_buffer = (unsigned long)rbuf;

    inst = (inst_buf_t *)txn->tdata.data.ptr.buffer;
    INST_INIT(inst);

    ibuf = malloc((iterations + 1) * sizeof(inst_entry_t) * INST_MAX_ENTRIES);
    if (!ibuf)
        fprintf(stderr, "client %d failed to allocate instrumentation buffer\n", id);

    p = ibuf;
    n = iterations + 1;
    while (n-- > 0) {
        INST_BEGIN(inst);

        retries = 2;

        bwr.write_size = sizeof(*txn);
        bwr.write_consumed = 0;
        bwr.read_size = sizeof(rbuf);
        bwr.read_consumed = 0;

        INST_ENTRY(inst, "C_SEND");

        ioctl_write++;
wait_reply:
        ioctl_read++;
        r = ioctl(fd, BINDER_WRITE_READ, &bwr);
        if (r < 0) {
            fprintf(stderr, "client %d failed ioctl\n", id);
            return r;
        }
        INST_RECORD(&copy);

        r = client_parse_command(id, rbuf, bwr.read_consumed, &inst_reply);
        if (r < 0)
            return r;

        if (!inst_reply) {
            //hexdump(rbuf, bwr.read_consumed);
            if (retries-- > 0) {
                bwr.write_size = 0;
                bwr.read_consumed = 0;
                goto wait_reply;
            } else {
                fprintf(stderr, "client %d failed to receive reply\n", id);
                return -1;
            }
        }

        memcpy(inst, inst_reply, sizeof(*inst)+data_SZ);
        //acsiidump(inst_reply,sizeof(*inst)+data_SZ);
        INST_ENTRY_COPY(inst, "C_RECV", &copy);
        INST_END(inst, &p);

#if (defined(SIMULATE_FREE_BUFFER) || !defined(INLINE_TRANSACTION_DATA))
        if (FREE_BUFFER(fd, inst_reply) < 0) {
            fprintf(stderr, "client %d: failed to free shared buffer\n", id);
            return -1;
        }
#endif
    }

    if (output_file) {
        if (clients > 1) {
            char *p = malloc(strlen(output_file) + 16);

            if (!p) {
                fprintf(stderr, "client %d failed to alloc memory for filename\n", id);
                return -1;
            }
            sprintf(p, "%s-%d", output_file, id);
            output_file = p;
        }

        fp = fopen(output_file, "w");
        if (!fp) {
            fprintf(stderr, "client %d failed to open dump file\n", id);
            return -1;
        }
    } else
        fp = stdout;

    memset(total_usecs, 0, sizeof(total_usecs));
    memset(max,0,sizeof(max));
    memset(min,255,sizeof(min));
    entry = (inst_entry_t *)ibuf;

    int i;
    //acsiidump(ibuf,80);
    for (n = 0; n < inst->seq; n++) {
        for (m = 0; m < inst->next_entry; m++) {
            if (n > 0) {
                if (m == 0) {
                    if (time_ref == 0)	// absolute time
                        ref.tv_sec = ref.tv_usec = 0;
                    else
                        ref = entry->tv;
                }

                delta.tv_sec = entry->tv.tv_sec - ref.tv_sec;
                delta.tv_usec = entry->tv.tv_usec - ref.tv_usec;
                if (delta.tv_usec < 0) {
                    delta.tv_sec--;
                    delta.tv_usec += 1000000;
                }
                record[m] = delta.tv_sec * 1000000 + delta.tv_usec;

                //fprintf(fp, "%ld.%06ld\t", delta.tv_sec, delta.tv_usec);

                if (time_ref > 0) {
                    total_usecs[m] += delta.tv_sec * 1000000 + delta.tv_usec;
                    if( m == inst->next_entry -1) {
                        if (min[m] > record[m] ) {
                            for( i = 0; i < inst->next_entry; i++ ) {
                                min[i] = record[i];
                            }
                        }
                        if (max[m] < record[m] ) {
                            for( i = 0; i < inst->next_entry; i++ ) {
                                max[i] = record[i];
                            }
                        }
                    }
                }
                if (time_ref > 1)	// relative to the previous entry
                    ref = entry->tv;
            } else {
                //fprintf(fp, "%8s\t", entry->label);
                if (time_ref > 0)
                    strcpy(labels[m], entry->label);
            }

            entry++;
        }
        //fprintf(fp, "\n");
    }

    if (fp != stdout)
        fclose(fp);
    free(txn);

    pid =getpid();
    printf("client(%d) %d: ioctl read: %u\n",pid,id, ioctl_read);
    printf("client(%d) %d: ioctl write: %u\n",pid,id, ioctl_write);
    printf("client(%d) %d: ioctl buffer: %u\n",pid,id, ioctl_buffer);

    if (time_ref > 0 && iterations > 0) {
        int pos = 0,minpos=0,maxpos=0;
        char *buf = malloc(64 * m);
        char *minbuf = malloc(64 * m);
        char *maxbuf = malloc(64 * m);

        if (!buf||!minbuf||!maxbuf)
            return 1;
        for (n = 0; n < m; n++) {
            pos += sprintf(buf + pos, "\t%s: %lld.%02lldus\n", labels[n],
                           (total_usecs[n] / iterations),
                           (total_usecs[n] % iterations) * 100 / iterations);

            minpos += sprintf(minbuf + minpos, "\t%s: %lldus\n", labels[n],
                              min[n]);
            maxpos += sprintf(maxbuf + maxpos, "\t%s: %lldus\n", labels[n],
                              max[n]);
        }
        printf("client %d: average results:\n%s\n", id, buf);
        printf("client %d: min results:\n%s\n", id, minbuf);
        printf("client %d: max results:\n%s\n", id, maxbuf);
        free(buf);
        free(minbuf);
        free(maxbuf);
    }
    return 0;
}