static ErlDrvData reg_start(ErlDrvPort port, char* buf) { RegPort* rp; char* s; REGSAM sam = KEY_READ; if ((s = strchr(buf, ' ')) != NULL) { while (isspace(*s)) s++; while (*s != '\0') { if (*s == 'r') { sam |= KEY_READ; } else if (*s == 'w') { sam |= KEY_WRITE; } s++; } } rp = driver_alloc(sizeof(RegPort)); if (rp == NULL) { return ERL_DRV_ERROR_GENERAL; } rp->port = port; rp->hkey = rp->hkey_root = HKEY_CLASSES_ROOT; rp->sam = sam; rp->key = driver_alloc(1); rp->key_size = 0; rp->name_buf_size = 64; rp->name_buf = driver_alloc(rp->name_buf_size); rp->value_buf_size = 64; rp->value_buf = driver_alloc(rp->value_buf_size); return (ErlDrvData) rp; }
char *escape_quotes(char *text) { int bufsize = strlen(text) * 2; char *buf = (char *) driver_alloc(bufsize); memset(buf, 0, bufsize); int i = 0; int x = 0; int escaped = 0; for (i = 0; i < strlen(text); i++) { if (text[i] == '"') { if(!escaped) { memcpy(&buf[x], (char *) "\\\"", 2); x += 2; } else { memcpy(&buf[x], &text[i], 1); x++; } } else { if(text[i] =='\\') { escaped = 1; } else { escaped = 0; } memcpy(&buf[x], &text[i], 1); x++; } } char *retval = (char *) driver_alloc(strlen(buf) + 1); memset(retval, 0, strlen(buf) + 1); strncpy(retval, buf, strlen(buf)); driver_free(buf); return retval; }
static void fill_passwd (ErlDrvTermData *data, struct passwd *pwd, char **name, char **passwd) { char *pw_name = pwd->pw_name; char *pw_passwd = pwd->pw_passwd; size_t len_name = strlen (pw_name); size_t len_passwd = strlen (pw_passwd); if (name) { *name = (char *) driver_alloc (sizeof (char) * (len_name + 1)); memcpy (*name, pw_name, sizeof (char) * (len_name + 1)); pw_name = *name; } if (passwd) { *passwd = (char *) driver_alloc (sizeof (char *) * (len_passwd + 1)); memcpy (*passwd, pw_passwd, sizeof (char) * (len_passwd + 1)); pw_passwd = *passwd; } *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_name"); *data++ = ERL_DRV_STRING; *data++ = (ErlDrvTermData) pw_name; *data++ = strlen (pwd->pw_name); *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_passwd"); *data++ = ERL_DRV_STRING; *data++ = (ErlDrvTermData) pw_passwd; *data++ = strlen (pwd->pw_name); *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_uid"); *data++ = ERL_DRV_UINT; *data++ = pwd->pw_uid; *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_ATOM; *data++ = driver_mk_atom ("pw_gid"); *data++ = ERL_DRV_UINT; *data++ = pwd->pw_gid; *data++ = ERL_DRV_TUPLE; *data++ = 2; *data++ = ERL_DRV_TUPLE; *data++ = 4; }
static void standard_outputv(ErlDrvData drv_data, ErlIOVec* ev) { wxe_data* sd = (wxe_data *) drv_data; WXEBinRef * binref; ErlDrvBinary* bin; if(ev->vsize == 2) { binref = driver_alloc(sizeof(WXEBinRef)); binref->base = ev->iov[1].iov_base; binref->size = ev->iov[1].iov_len; binref->from = driver_caller(sd->port); bin = ev->binv[1]; driver_binary_inc_refc(bin); /* Otherwise it could get deallocated */ binref->bin = bin; binref->next = sd->bin; sd->bin = binref; } else { /* Empty binary (becomes NULL) */ binref = driver_alloc(sizeof(WXEBinRef)); binref->base = NULL; binref->size = 0; binref->from = driver_caller(sd->port); binref->bin = NULL; binref->next = sd->bin; sd->bin = binref; } }
decode_result process_data(ErlDrvData handle,unsigned char* buf, ErlDrvSizeT* sz,char*& html_content,char*& url_address){ int index = 0,size=0,type=0,ver=0; if (ei_decode_version((char*)buf, &index,&ver)){ //data encoding version mismatch return decode_result{false,std::pair<std::string,std::string>("",""), "data encoding version mismatch"}; } else if (ei_get_type((char*)buf,&index,&type,&size)){ //must be a binary return decode_result{false,std::pair<std::string,std::string>("",""), "must be a binary"}; } else{ int tuple_arity; ei_decode_tuple_header((char*)buf,&index,&tuple_arity); ei_get_type((char*)buf,&index,&type,&size); url_address = (char*)driver_alloc((size+2)*sizeof(char)); ei_decode_string((char*)buf,&index,url_address); ei_get_type((char*)buf,&index,&type,&size); //cout << "Html Content Size " << size << endl; html_content = (char*)driver_alloc((size+2)*sizeof(char)); ei_decode_string((char*)buf,&index,html_content); *sz = size; std::string url_address_str(url_address); std::string html_content_str(html_content); return decode_result{true,std::pair<std::string,std::string>(url_address_str,html_content_str),NULL}; } }
static ErlDrvData ejabberd_zlib_drv_start(ErlDrvPort port, char *buff) { ejabberd_zlib_data *d = (ejabberd_zlib_data *)driver_alloc(sizeof(ejabberd_zlib_data)); d->port = port; d->d_stream = (z_stream *)driver_alloc(sizeof(z_stream)); d->d_stream->zalloc = zlib_alloc; d->d_stream->zfree = zlib_free; d->d_stream->opaque = (voidpf)0; deflateInit(d->d_stream, Z_DEFAULT_COMPRESSION); d->i_stream = (z_stream *)driver_alloc(sizeof(z_stream)); d->i_stream->zalloc = zlib_alloc; d->i_stream->zfree = zlib_free; d->i_stream->opaque = (voidpf)0; inflateInit(d->i_stream); set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); return (ErlDrvData)d; }
static ErlDrvData exmpp_xml_start(ErlDrvPort port, char *command) { struct exmpp_xml_data *edd; /* Set binary mode. */ set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); /* Allocate driver data structure. */ edd = driver_alloc(sizeof(*edd)); if (edd == NULL) return (ERL_DRV_ERROR_GENERAL); /* Initialize generic context. */ if (init_context(&edd->ctx) != 0) { driver_free(edd); return (ERL_DRV_ERROR_GENERAL); } edd->ctx.make_attributes = exmpp_xml_cb_make_attributes; /* Initialize driver instance's context. */ edd->parser = NULL; /* Initialize the declared_nss list. */ edd->declared_nss = driver_alloc(sizeof(*(edd->declared_nss))); if (edd->declared_nss == NULL) { free_context(&edd->ctx); driver_free(edd); return (ERL_DRV_ERROR_GENERAL); } ei_x_new(edd->declared_nss); return ((ErlDrvData)edd); }
int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) { ErlDrvBinary* bin; int i; int num_vertices; GLdouble *n; int AP; int a_max = 2; int i_max = 6; num_vertices = * (int *) buff; buff += 8; /* Align */ n = (double *) buff; buff += 8*3; egl_tess.alloc_max = a_max*num_vertices*3; bin = driver_alloc_binary(egl_tess.alloc_max*sizeof(GLdouble)); egl_tess.error = 0; egl_tess.tess_coords = (double *) bin->orig_bytes; memcpy(egl_tess.tess_coords,buff,num_vertices*3*sizeof(GLdouble)); egl_tess.index_max = i_max*3*num_vertices; egl_tess.tess_index_list = (int *) driver_alloc(sizeof(int) * egl_tess.index_max); egl_tess.tess_coords = (double *) bin->orig_bytes; egl_tess.index_n = 0; egl_tess.alloc_n = num_vertices*3; gluTessNormal(tess, n[0], n[1], n[2]); gluTessBeginPolygon(tess, 0); gluTessBeginContour(tess); for (i = 0; i < num_vertices; i++) { gluTessVertex(tess, egl_tess.tess_coords+3*i, egl_tess.tess_coords+3*i); } gluTessEndContour(tess); gluTessEndPolygon(tess); AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+egl_tess.index_n*2)); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(i=0; i < egl_tess.index_n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) egl_tess.tess_index_list[i]; }; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = egl_tess.index_n+1; rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; rt[AP++] = egl_tess.alloc_n*sizeof(GLdouble); rt[AP++] = 0; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple driver_send_term(port,caller,rt,AP); /* fprintf(stderr, "List %d: %d %d %d \r\n", */ /* res, */ /* n_pos, */ /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */ /* num_vertices*6*sizeof(GLdouble)); */ driver_free_binary(bin); driver_free(egl_tess.tess_index_list); driver_free(rt); return 0; }
int exmpp_ht_store(struct exmpp_hashtable *ht, const char *key, int key_len, void *value) { unsigned int index; struct exmpp_ht_entry *entry; if (ht == NULL || ht->entries == NULL) return (-1); /* Allocate the new entry. */ entry = driver_alloc(sizeof(*entry)); if (entry == NULL) return (-1); if (key_len == -1) { entry->hash = ht_hash(key); entry->key = exmpp_strdup(key); if (entry->key == NULL) return (-1); } else { entry->hash = ht_hash_len(key, key_len); entry->key = driver_alloc(key_len + 1); if (entry->key == NULL) return (-1); memcpy(entry->key, key, key_len); entry->key[key_len] = '\0'; } entry->key_len = key_len; entry->value = value; #if defined(USE_RWLOCK) erl_drv_rwlock_rwlock(ht->lock); #endif /* Expand the table is necessary. */ if (++(ht->entries_count) > ht->load_limit) { /* * Ignore the return value. If expand fails, we should * still try cramming just this value into the existing * table -- we may not have memory for a larger table, * but one more element may be ok. Next time we insert, * we'll try expanding again. */ ht_expand(ht); } /* Wire the new entry. */ index = entry->hash % ht->length; entry->next = ht->entries[index]; ht->entries[index] = entry; #if defined(USE_RWLOCK) erl_drv_rwlock_rwunlock(ht->lock); #endif return (0); }
static int get_pwall (pwd_drv_t *drv) { size_t pwd_count = 0; setpwent (); while (getpwent ()) pwd_count++; endpwent (); size_t term_count = passwd_term_count (); size_t result_count = pwd_count * term_count; ErlDrvTermData *result = (ErlDrvTermData *) driver_alloc (sizeof (ErlDrvTermData) * (result_count + 3)); if (!result) { fprintf (drv->log, "Couldn't allocate memory for result\n"); fflush (drv->log); return send_error (drv, "error", "Couldn't allocate memory for result"); } char **names = (char **) driver_alloc (sizeof (char *) * pwd_count); char **pwds = (char **) driver_alloc (sizeof (char *) * pwd_count); setpwent (); size_t result_idx = 0; struct passwd *pwd = getpwent (); while (pwd) { fill_passwd (&result[result_idx * term_count], pwd, &names[result_idx], &pwds[result_idx]); result_idx++; pwd = getpwent (); } endpwent (); result[result_count++] = ERL_DRV_NIL; result[result_count++] = ERL_DRV_LIST; result[result_count++] = pwd_count + 1; int r = driver_output_term (drv->port, result, result_count); size_t i = 0; for (; i < pwd_count; ++i) { driver_free (pwds[i]); driver_free (names[i]); } driver_free (pwds); driver_free (names); driver_free (result); return r; }
static ErlDrvData hash_ring_drv_start(ErlDrvPort port, char *buff) { hash_ring_data* d = (hash_ring_data*)driver_alloc(sizeof(hash_ring_data)); d->port = port; d->numRings = INITIAL_RING_SPACE; d->rings = (hash_ring_t**)driver_alloc(sizeof(hash_ring_t) * d->numRings); d->ring_usage = (unsigned char*)driver_alloc(sizeof(unsigned char) * d->numRings); memset(d->ring_usage, 0, sizeof(unsigned char) * d->numRings); return (ErlDrvData)d; }
static inline async_sqlite3_command *make_async_command_script( sqlite3_drv_t *drv, char *script, int script_length) { async_sqlite3_command *result = (async_sqlite3_command *) driver_alloc(sizeof(async_sqlite3_command)); char *script_copy = driver_alloc(sizeof(char) * script_length); memset(result, 0, sizeof(async_sqlite3_command)); memcpy(script_copy, script, sizeof(char) * script_length); result->driver_data = drv; result->type = t_script; result->script = script_copy; result->end = script_copy + script_length; return result; }
// Any string read using this function must be freed // using driver_free later char *read_string(char **data) { int length = read_int32(data); char *buf = NULL; if (length > 0) { buf = (char *) driver_alloc(length + 1); memset(buf, 0, length + 1); memcpy(buf, (const char *) *data, length); (*data) += length; } else { buf = (char *) driver_alloc(1); memset(buf, 0, 1); } return buf; }
static ErlDrvData start(ErlDrvPort port, char *) { if (NULL != port) { void *ptr = driver_alloc(sizeof(driver_data_t)); if (NULL != ptr) { set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); driver_data_t *data = (driver_data_t *)ptr; data->port = port; strcpy(data->path, "flat_in/"); // << EGenLoader.cpp: FLAT_IN_PATH TPCE::CDriverGlobalSettings dgs; TPCE::TDriverGlobalSettings &dgs_d = dgs.dft; data->configured_customer_count = dgs_d.iConfiguredCustomerCount; data->active_customer_count = dgs_d.iActiveCustomerCount; data->scale_factor = dgs_d.iScaleFactor; data->days_of_initial_trades = dgs_d.iDaysOfInitialTrades; return (ErlDrvData)data; } } return ERL_DRV_ERROR_GENERAL; }
static ErlDrvData tcbdb_start (ErlDrvPort port, char* buf) { ErlDrvSysInfo info; TcDriverData* d = (TcDriverData*) driver_alloc (sizeof (TcDriverData)); (void) buf; memset (d, 0, sizeof (TcDriverData)); d->ref_count = 1; d->port = port; d->bdb = tcbdbnew (); driver_system_info (&info, sizeof (info)); if (info.thread_support && info.async_threads > 0) { d->async_threads = 1; } d->cur = tcbdbcurnew (d->bdb); init_handlers (d->handlers); d->magic = ((intptr_t) d) >> 8; return (ErlDrvData) d; }
/* DRIVER INTERFACE */ static ErlDrvData start(ErlDrvPort port, char *command) { our_data_t* data = driver_alloc(sizeof(our_data_t)); data->port = port; data->conn = NULL; return (ErlDrvData)data; }
static ErlDrvData start(ErlDrvPort port, char *command) { mcd_data_t *mcd = driver_alloc(sizeof(mcd_data_t)); if (!mcd) goto error; mcd->ofd = -1; mcd->ifd = -1; #ifdef UNIX mcd->ofd = open("/dev/null", O_WRONLY); if (mcd->ofd < 0) goto error; if (driver_select(port, (ErlDrvEvent) (long) mcd->ofd, DO_WRITE, 1) != 0) goto error; mcd->ifd = open("/dev/zero", O_RDONLY); if (mcd->ifd < 0) goto error; if (driver_select(port, (ErlDrvEvent) (long) mcd->ifd, DO_READ, 1) != 0) goto error; #endif driver_set_timer(port, 0); return (ErlDrvData) mcd; error: stop((ErlDrvData) mcd); return ERL_DRV_ERROR_GENERAL; }
//======================================================================= // ERL_DRIVER CALLBACKS static ErlDrvData init(ErlDrvPort port, char *cmd) { tcbdb_drv_t *driver; driver = driver_alloc(sizeof(tcbdb_drv_t)); driver->port = port; driver->bdb = NULL; return (ErlDrvData)driver; }
static int state_reply(RegPort* rp, /* Pointer to port structure. */ HKEY root, /* Handle to root key for this key. */ LPSTR name, /* Pointer to name. */ DWORD nameSize) /* Length of name. */ { char sbuf[512]; char* s = sbuf; int needed = 1+4+nameSize; int i; if (sizeof sbuf < needed) { s = driver_alloc(needed); } s[0] = 's'; i = 1; put_int32((DWORD) root, s+i); i += 4; memcpy(s+i, name, nameSize); ASSERT(i+nameSize == needed); driver_output(rp->port, s, needed); if (s != sbuf) { driver_free(s); } return 1; }
static ErlDrvData start(ErlDrvPort port, char *command) { Otp9302Data *data; ErlDrvSysInfo sys_info; data = driver_alloc(sizeof(Otp9302Data)); if (!data) return ERL_DRV_ERROR_GENERAL; data->port = port; driver_system_info(&sys_info, sizeof(ErlDrvSysInfo)); data->smp = sys_info.smp_support; if (!data->smp) { data->msgq.start = NULL; data->msgq.end = NULL; data->msgq.mtx = erl_drv_mutex_create(""); if (!data->msgq.mtx) { driver_free(data); return ERL_DRV_ERROR_GENERAL; } } return (ErlDrvData) data; }
void bdberl_tpool_run(TPool* tpool, TPoolJobFunc main_fn, void* arg, TPoolJobFunc cancel_fn, TPoolJob** job_ptr) { // Allocate and fill a new job structure TPoolJob* job = *job_ptr = driver_alloc(sizeof(TPoolJob)); memset(job, '\0', sizeof(TPoolJob)); job->main_fn = main_fn; job->arg = arg; job->cancel_fn = cancel_fn; // Sync up with the tpool and add the job to the pending queue LOCK(tpool); if (tpool->pending_jobs) { // Make sure the current last job points to this one next tpool->last_pending_job->next = job; } else { // No pending jobs; this is the first tpool->pending_jobs = job; } tpool->last_pending_job = job; tpool->pending_job_count++; // Generate a notification that there is work todo. // TODO: I think this may not be necessary, in the case where there are already other // pending jobs. Not sure ATM, however, so will be on safe side erl_drv_cond_broadcast(tpool->work_cv); UNLOCK(tpool); }
static int control_control(ErlDrvData port, unsigned command, char* buf, int count, char** res, int res_size) { switch (command) { case 'e': if (count > res_size) { *res = (char *) driver_alloc(count); } memcpy(*res, buf, count); return count; case 'b': set_busy_port(erlang_port, buf[0]); return 0; case 'i': driver_output(erlang_port, buf, count); return 0; default: if (command < 256) { return -1; } else { char* p = *res; int i; for (i = 3; i >= 0; i--) { p[i] = command; command >>= 8; } return 4; } } }
static ErlDrvData drv_start(ErlDrvPort port, char *command){ drv_data_t* d = (drv_data_t*)driver_alloc(sizeof(drv_data_t)); d->port = port; return (ErlDrvData)d; }
static void process(ErlDrvData handle, ErlIOVec *ev) { spidermonkey_drv_t *dd = (spidermonkey_drv_t *) handle; char *data = ev->binv[1]->orig_bytes; char *command = read_command(&data); if (strncmp(command, "ij", 2) == 0) { char *call_id = read_string(&data); int thread_stack = read_int32(&data); if (thread_stack < 8) { thread_stack = 8; } thread_stack = thread_stack * (1024 * 1024); int heap_size = read_int32(&data) * (1024 * 1024); dd->vm = sm_initialize(thread_stack, heap_size); send_ok_response(dd, call_id); driver_free(call_id); } else { js_call *call_data = (js_call *) driver_alloc(sizeof(js_call)); call_data->driver_data = dd; call_data->args = ev->binv[1]; driver_binary_inc_refc(call_data->args); ErlDrvPort port = dd->port; unsigned long thread_key = (unsigned long) port; driver_async(dd->port, (unsigned int *) &thread_key, (asyncfun) run_js, (void *) call_data, NULL); } driver_free(command); }
static ErlDrvData emonk_start(ErlDrvPort port, char *cmd) { uint rt_max, gc_max, gc_last, ctx; emonk_drv_t* drv = NULL; ErlDrvData ret = ERL_DRV_ERROR_GENERAL; emonk_settings_t settings; if(parse_settings(cmd, &settings) < 0) { ret = ERL_DRV_ERROR_BADARG; goto error; } drv = (emonk_drv_t*) driver_alloc(sizeof(emonk_drv_t)); if(drv == NULL) goto error; drv->port = port; drv->ok = driver_mk_atom("ok"); drv->error = driver_mk_atom("error"); drv->undefined = driver_mk_atom("undefined"); drv->bad_cmd = driver_mk_atom("bad_command"); drv->vm = init_vm(&settings); if(drv->vm == NULL) goto error; return (ErlDrvData) drv; error: if(drv != NULL) driver_free(drv); return ret; }
void wxeFifo::Realloc() { unsigned int i; unsigned int growth = m_orig_sz / 2; unsigned int new_sz = growth + m_max; unsigned int max = m_max; unsigned int first = m_first; unsigned int n = m_n; wxeCommand * old = m_q; wxeCommand * queue = (wxeCommand *)driver_alloc(new_sz*sizeof(wxeCommand)); // fprintf(stderr, "\r\nrealloc qsz %d\r\n", new_sz);fflush(stderr); m_max=new_sz; m_first = 0; m_n=0; m_q = queue; for(i=0; i < n; i++) { unsigned int pos = (i+first)%max; if(old[pos].op >= 0) Append(&old[pos]); } for(i = m_n; i < new_sz; i++) { // Reset the rest m_q[i].buffer = NULL; m_q[i].op = -1; } // Can not free old queue here it can be used in the wx thread m_old = old; }
static void output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) { Otp9302Data *data = (Otp9302Data *) drv_data; ErlDrvTermData td_port = driver_mk_port(data->port); ErlDrvTermData td_receiver = driver_caller(data->port); ErlDrvTermData td_job = driver_mk_atom("job"); unsigned int key = (unsigned int) (ErlDrvSInt) data->port; long id[5]; Otp9302AsyncData *ad[5]; int i; for (i = 0; i < sizeof(ad)/sizeof(ad[0]); i++) { ad[i] = driver_alloc(sizeof(Otp9302AsyncData)); if (!ad[i]) abort(); ad[i]->smp = data->smp; ad[i]->port = data->port; ad[i]->block = 0; ad[i]->refc = 1; ad[i]->term_data.port = td_port; ad[i]->term_data.receiver = td_receiver; ad[i]->term_data.msg = td_job; ad[i]->msgq = &data->msgq; } ad[0]->block = 1; ad[0]->term_data.msg = driver_mk_atom("block"); ad[2]->term_data.msg = driver_mk_atom("cancel"); ad[4]->term_data.msg = driver_mk_atom("end_of_jobs"); for (i = 0; i < sizeof(id)/sizeof(id[0]); i++) id[i] = driver_async(data->port, &key, async_invoke, ad[i], driver_free); if (id[2] > 0) driver_async_cancel(id[2]); }
/*! * Callback to initialize the application-relevant state data when opening the * port driver and to return a pointer to the newly created driver state. * * \return Driver state */ extern void * init(void) { gdt_drv_t *drv; if ((drv = driver_alloc(sizeof(gdt_drv_t)))) /* destroy */ drv->count = 0; return drv; }
char *copy_string(const char *source) { int size = strlen(source) + 1; char *retval = driver_alloc(size); memset(retval, 0, size); strncpy(retval, source, size - 1); return retval; }
/*! * Initialize any thread-specific data. This is called, when first dispatching * a request to a thread. * * \return Thread state */ extern void * thread_init(void) { gdt_trd_t *trd; if ((trd = driver_alloc(sizeof(gdt_trd_t)))) /* thread_destroy */ trd->count = 0; return trd; }