void jv_thread_destroy(jv_thread_t *thread) { jv_active_thread_t *activep; jv_job_thread_t *jv_thread_job; (void) pthread_mutex_lock(&thread->mutex); pthread_cleanup_push ( (void (*) (void*)) pthread_mutex_unlock, &thread->mutex); /* mark the thread as being destroyed; wakeup idle workers */ thread->flag |= JV_THREAD_DESTROY; (void) pthread_cond_broadcast(&thread->workcv); /* cancel all active workers */ for (activep = thread->active; activep != NULL; activep = activep->next) (void) pthread_cancel(activep->tid); /* wait for all active workers to finish */ while (thread->active != NULL) { thread->flag |= JV_THREAD_WAIT; (void) pthread_cond_wait(&thread->waitcv, &thread->mutex); } /* the last worker to terminate will wake us up */ while (thread->count != 0) (void) pthread_cond_wait(&thread->busycv, &thread->mutex); pthread_cleanup_pop(1); /* pthread_mutex_unlock(&thread->mutex); */ /* * Unlink the thread from the global list of all threads. */ (void) pthread_mutex_lock(&jv_thread_lock); if (jv_threads == thread) jv_threads = thread->forw; if (jv_threads == thread) jv_threads = NULL; else { thread->back->forw = thread->forw; thread->forw->back = thread->back; } (void) pthread_mutex_unlock(&jv_thread_lock); /* There should be no pending jv_thread_jobs, but just in case... */ for (jv_thread_job = thread->head; jv_thread_job != NULL; jv_thread_job = thread->head) { thread->head = jv_thread_job->next; jv_pool_free(thread->pool, jv_thread_job); } (void) pthread_attr_destroy(&thread->attr); jv_pool_free(thread->pool, thread); }
void *test_pool5(void *arg){ jv_pool_t *pool=(jv_pool_t *)arg; jv_uint_t i; srand(time(NULL)); for(i=0;i<100;i++){ jv_uint_t j=rand()%100; jv_lump_t *lump=jv_pool_alloc(pool,j); if(lump==NULL){ printf("free is error.\n"); continue; } jv_pool_free(pool,lump); } each(pool); return NULL; }
void test3(void) { jv_pool_t *pool; jv_uint_t i; pool=jv_pool_create(4096); each(pool); srand(time(NULL)); for(i=0;i<100;i++) { jv_uint_t j = rand()%100 + 500; jv_lump_t* lump = (jv_lump_t*)jv_pool_alloc(pool,j); printf("apply memory size:%u\n",j); if(lump==NULL) { printf("free is error.\n"); continue; } jv_pool_free(pool,lump); } each(pool); jv_pool_destroy(pool); }
void test2(void) { jv_pool_t *pool; void *a,*b,*c,*d,*e,*f,*g,*h; jv_lump_t *lump; /* printf("sizeof(jv_pool_t):%u\n",sizeof(jv_pool_t)); */ //pool=jv_pool_create(128); pool=jv_pool_create(5000 * (4096 + 16 * 3)); // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("\n"); // assert((u_char *)pool->first+sizeof(jv_block_t)==(u_char *)pool); // assert((u_char *)pool->first+sizeof(jv_block_t)+sizeof(jv_pool_t)==(u_char *)pool->lump); // assert((u_char *)pool+sizeof(jv_pool_t)==(u_char *)(pool->lump)); // a=jv_pool_alloc(pool,40); // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("a address:%u,pos:%u\n",(jv_uint_t)a,(jv_uint_t)pool->pos); // assert((u_char *)a==(u_char *)pool+sizeof(jv_pool_t)+sizeof(jv_lump_t)+32+sizeof(jv_lump_t)); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // b=jv_pool_alloc(pool,56); // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("b address:%u,pos:%u\n",(jv_uint_t)b,(jv_uint_t)pool->pos); // assert((u_char *)b==(u_char *)pool->first->next+sizeof(jv_block_t)+sizeof(jv_lump_t)+52); // //each(pool); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // c=jv_pool_alloc(pool,32); /* (32,36) */ // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("c address:%u,pos:%u\n",(jv_uint_t)c,(jv_uint_t)pool->pos); // assert((u_char *)c==(u_char *)pool->first->next+sizeof(jv_block_t)+sizeof(jv_lump_t)); //// each(pool); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // d=jv_pool_alloc(pool,8); // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("d address:%u,pos:%u\n",(jv_uint_t)d,(jv_uint_t)pool->pos); // assert((u_char *)d==(u_char *)pool+sizeof(jv_pool_t)+sizeof(jv_lump_t)+24); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // e=jv_pool_alloc(pool,4); /* (4,8) */ // printf("pool:%u,pos:%u,block:%u,block->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("e address:%u,pos:%u\n",(jv_uint_t)e,(jv_uint_t)pool->pos); // assert((u_char *)e==(u_char *)pool+sizeof(jv_pool_t)+sizeof(jv_lump_t)); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // f=jv_pool_alloc(pool,24); // printf("pool:%u,pos:%u,block:%u,block->next->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("f address:%u,pos:%u\n",(jv_uint_t)f,(jv_uint_t)pool->pos); // assert((u_char *)f==(u_char *)pool->first->next->next+sizeof(jv_block_t)+sizeof(jv_lump_t)+68+sizeof(jv_lump_t)); // printf("\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n\n"); // g=jv_pool_alloc(pool,104); // printf("pool:%u,pos:%u,block:%u,block->next->next:%u,lump:%u,lump->next:%u\n",(jv_uint_t)pool,(jv_uint_t)pool->pos,(jv_uint_t)pool->first,(jv_uint_t)pool->first->next->next,(jv_uint_t)pool->lump,(jv_uint_t)pool->lump->next); // printf("g address:%u,pos:%u\n",(jv_uint_t)g,(jv_uint_t)pool->pos); // assert((u_char *)g==(u_char *)pool->first->next->next->next+sizeof(jv_block_t)+sizeof(jv_lump_t)); /*jeach(pool); v_pool_free(pool,c); lump=((jv_lump_t *)((u_char *)pool->first->next+sizeof(jv_block_t))); assert(lump->used==0); assert(lump->size==36); jv_pool_free(pool,f); lump=((jv_lump_t *)((u_char *)pool->first->next->next+sizeof(jv_block_t)+sizeof(jv_lump_t)+68)); assert(lump->used==0); assert(lump->size==24); jv_pool_free(pool,a); lump=((jv_lump_t *)((u_char *)pool->first+sizeof(jv_block_t)+sizeof(jv_pool_t)+sizeof(jv_lump_t)+32)); assert(lump->used==0); assert(lump->size==40); jv_pool_free(pool,e); lump=((jv_lump_t *)((u_char *)pool->first+sizeof(jv_block_t)+sizeof(jv_pool_t))); assert(lump->used==0); assert(lump->size==8); jv_pool_free(pool,d); lump=((jv_lump_t *)((u_char *)pool->first+sizeof(jv_block_t)+sizeof(jv_pool_t))); assert(lump->used==0); assert(lump->size==88); jv_pool_free(pool,b); lump=((jv_lump_t *)((u_char *)pool->first->next+sizeof(jv_block_t))); assert(lump->used==0); assert(lump->size==108); jv_pool_free(pool,g); lump=((jv_lump_t *)((u_char *)pool->first->next->next+sizeof(jv_block_t))); assert(lump->used==0); assert(lump->size==108);*/ each(pool); h=jv_pool_alloc(pool,1000); each(pool); jv_pool_free(pool,h); each(pool); /* char* sss = (char*)malloc(4); assert(jv_pool_free(pool, sss)==JV_ERROR); free(sss);*/ jv_pool_destroy(pool); }
static void *jv_worker_thread(void *arg) { jv_thread_t *thread = (jv_thread_t *) arg; jv_int_t timedout; jv_job_thread_t *job; void * (*func)(void *); jv_active_thread_t active; timestruc_t ts; /* * This is the worker's main loop. It will only be left * if a timeout occurs or if the thread is being destroyed. */ (void) pthread_mutex_lock(&thread->mutex); pthread_cleanup_push ( (void (*) (void*)) jv_worker_cleanup, thread); active.tid = pthread_self(); for (;;) { /* * We don't know what this thread was doing during * its last jv_thread_job, so we reset its signal mask and * cancellation state back to the initial values. */ (void) pthread_sigmask(SIG_SETMASK, &fillset, NULL); (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); (void) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); timedout = 0; thread->idle++; if (thread->flag & JV_THREAD_WAIT) jv_notify_waiters(thread); while (thread->head == NULL && !(thread->flag & JV_THREAD_DESTROY)) { if (thread->count <= thread->min) { (void) pthread_cond_wait(&thread->workcv, &thread->mutex); } else { (void) clock_gettime(CLOCK_REALTIME, &ts); ts.tv_sec += thread->linger; if (thread->linger == 0 || pthread_cond_timedwait (&thread->workcv, &thread->mutex, &ts) == ETIMEDOUT) { timedout = 1; break; } } } thread->idle--; if (thread->flag & JV_THREAD_DESTROY) break; if ((job = thread->head) != NULL) { timedout = 0; func = job->func; arg = job->arg; thread->head = job->next; if (job == thread->tail) thread->tail = NULL; active.next = thread->active; thread->active = &active; (void) pthread_mutex_unlock(&thread->mutex); pthread_cleanup_push ( (void (*) (void*)) jv_job_thread_cleanup, thread); jv_pool_free(thread->pool, job); (void) func(arg); /* Call the specified jv_thread_job function. */ /* * If the jv_thread_job function calls pthread_exit(), the thread * calls jv_job_thread_cleanup(thread) and jv_worker_cleanup(thread); * the integrity of the thread is thereby maintained. */ pthread_cleanup_pop(1); /* jv_job_thread_cleanup(thread) */ } if (timedout && thread->count > thread->min) { /* * We timed out and there is no work to be done and * the number of workers exceeds the minimum. * Exit now to reduce the size of the thread. */ break; } } pthread_cleanup_pop(1); /* jv_worker_cleanup(thread) */ return (NULL); }