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(©); 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", ©); 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; }