/** * @brief Free a pthread read/write lock attributes object. * @see pthread_rwlockattr_destroy() * @param attr a pointer to the read/write lock attributes object to be freed. * @return 0 on success or an error number on failure. */ int rwlock_attr_destroy(pthread_rwlockattr_t *attr) { #ifdef MAGMA_PEDANTIC int result = pthread_rwlockattr_destroy(attr); if (result) log_pedantic("Could not destroy the read/write lock attribute object. {pthread_rwlockattr_destroy = %i}", result); return result; #else return pthread_rwlockattr_destroy(attr); #endif }
int get_thread_attr() { pthread_attr_t attr; pthread_attr_init(&attr); print_thread_attr(&attr); pthread_attr_destroy(&attr); printf("\n"); pthread_mutexattr_t mutex_attr; pthread_mutexattr_init(&mutex_attr); print_mutexattr(&mutex_attr); pthread_mutexattr_destroy(&mutex_attr); printf("\n"); pthread_rwlockattr_t rwlock_attr; pthread_rwlockattr_init(&rwlock_attr); print_rwlockattr(&rwlock_attr); pthread_rwlockattr_destroy(&rwlock_attr); printf("\n"); pthread_condattr_t cond_attr; pthread_condattr_init(&cond_attr); print_condattr(&cond_attr); pthread_condattr_destroy(&cond_attr); printf("\n"); return THREAD_ATTR_OK; }
void test_rwlock_init(void) { int rc; pthread_rwlockattr_t attrs; rc = pthread_rwlockattr_init(&attrs); ASSERT_EQ(rc, 0); int shared = -1; rc = pthread_rwlockattr_getpshared(&attrs, &shared); ASSERT_EQ(rc, 0); ASSERT_EQ(shared, PTHREAD_PROCESS_PRIVATE); rc = pthread_rwlockattr_setpshared(&attrs, PTHREAD_PROCESS_SHARED); #ifndef __GLIBC__ /* * glibc's pthread_rwlockattr_setpshared doesn't currently fail * with PTHREAD_PROCESS_SHARED. TODO(sbc): remove this once * we fix the glibc bug: * https://code.google.com/p/nativeclient/issues/detail?id=4142 */ ASSERT_EQ(rc, EINVAL); #endif rc = pthread_rwlockattr_setpshared(&attrs, PTHREAD_PROCESS_PRIVATE); ASSERT_EQ(rc, 0); rc = pthread_rwlock_init(&g_rwlock, &attrs); ASSERT_EQ(rc, 0); rc = pthread_rwlockattr_destroy(&attrs); ASSERT_EQ(rc, 0); }
struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) { #ifdef OBSOLETE_LINUX_KERNEL return uwsgi_lock_fast_init(id); #else pthread_rwlockattr_t attr; struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 1); if (pthread_rwlockattr_init(&attr)) { uwsgi_log("unable to allocate rwlock structure\n"); exit(1); } if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) { uwsgi_log("unable to share rwlock\n"); exit(1); } if (pthread_rwlock_init((pthread_rwlock_t *) uli->lock_ptr, &attr)) { uwsgi_log("unable to initialize rwlock\n"); exit(1); } pthread_rwlockattr_destroy(&attr); uli->can_deadlock = 1; return uli; #endif }
int tsm_disconnect(TSMDevice * shm_device) { int ret; ret = TSM_SUCCESS; // if we had a read/write lock, destroy it first if (shm_device->rwlock_addr != NULL) { ret = pthread_rwlockattr_destroy(&shm_device->rwlattr); if (ret == -1) { perror("tsm_disconnect SHARED MEMORY DESTROY LOCK ATTRIBUTES FAILED"); } ret = pthread_rwlock_destroy(shm_device->rwlock_addr); if (ret == -1) { perror("tsm_disconnect SHARED MEMORY DESTROY LOCK FAILED"); } } ret = shmdt(shm_device->addr); if (ret == -1) { perror("tsm_disconnect SHARED MEMORY DETACH FAILED"); } return (ret); }
int main() { pthread_rwlockattr_t rwa; pthread_rwlock_t rwl1, rwl2; int rc; /* Initialize a read-write lock attributes object */ rc = pthread_rwlockattr_init(&rwa); if (rc != 0) { printf("Error at pthread_rwlockattr_init(), returns %d\n", rc); return PTS_UNRESOLVED; } if ((rc = pthread_rwlock_init(&rwl1, &rwa)) != 0) { printf("Error at 1st pthread_rwlock_init()\n"); return PTS_UNRESOLVED; } if ((rc = pthread_rwlock_init(&rwl2, &rwa)) != 0) { printf("Error at 2nd pthread_rwlock_init()\n"); return PTS_UNRESOLVED; } if ((rc = pthread_rwlock_rdlock(&rwl1)) != 0) { printf("Error at pthread_rwlock_rdlock(): rwl1\n"); return PTS_UNRESOLVED; } if ((rc = pthread_rwlockattr_destroy(&rwa)) != 0) { printf("Error at pthread_rwlockattr_destory()\n"); return PTS_UNRESOLVED; } if ((rc = pthread_rwlock_unlock(&rwl1)) != 0) { printf("Error at pthread_rwlock_unlock: rwl1\n"); printf("Test Failed.\n"); return PTS_FAIL; } if ((rc = pthread_rwlock_rdlock(&rwl2)) != 0) { printf("Error at pthread_rwlock_rdlock():rwl2\n"); printf("Test Failed.\n"); return PTS_FAIL; } if ((rc = pthread_rwlock_unlock(&rwl2)) != 0) { printf("Error at pthread_rwlock_unlock:rwl2\n"); printf("Test Failed.\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }
int __ast_rwlock_init(int tracking, const char *filename, int lineno, const char *func, const char *rwlock_name, ast_rwlock_t *t) { int res; pthread_rwlockattr_t attr; #ifdef DEBUG_THREADS #if defined(AST_MUTEX_INIT_W_CONSTRUCTORS) && defined(CAN_COMPARE_MUTEX_TO_INIT_VALUE) int canlog = strcmp(filename, "logger.c") & t->tracking; if (t->lock != ((pthread_rwlock_t) __AST_RWLOCK_INIT_VALUE)) { __ast_mutex_logger("%s line %d (%s): Warning: rwlock '%s' is already initialized.\n", filename, lineno, func, rwlock_name); return 0; } #endif /* AST_MUTEX_INIT_W_CONSTRUCTORS */ if ((t->tracking = tracking)) { ast_reentrancy_init(&t->track); } #endif /* DEBUG_THREADS */ pthread_rwlockattr_init(&attr); #ifdef HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NP pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP); #endif res = pthread_rwlock_init(&t->lock, &attr); pthread_rwlockattr_destroy(&attr); return res; }
/** \brief Initialize the rwlock taking the rwlock attributes into account * * \b os_rwlockInit calls \b pthread_rwlock_init to intialize the posix * \b rwlock. * * In case the scope attribute is \b OS_SCOPE_SHARED, the posix * \b rwlock "pshared" attribute is set to \b PTHREAD_PROCESS_SHARED * otherwise it is set to \b PTHREAD_PROCESS_PRIVATE. */ os_result os_rwlockInit ( os_rwlock *rwlock, const os_rwlockAttr *rwlockAttr) { pthread_rwlockattr_t rwattr; int result; os_result rv; assert (rwlock != NULL); assert (rwlockAttr != NULL); pthread_rwlockattr_init (&rwattr); if (rwlockAttr->scopeAttr == OS_SCOPE_SHARED) { result = pthread_rwlockattr_setpshared (&rwattr, PTHREAD_PROCESS_SHARED); } else { result = pthread_rwlockattr_setpshared (&rwattr, PTHREAD_PROCESS_PRIVATE); } if (result == 0) { pthread_rwlock_init (rwlock, &rwattr); } pthread_rwlockattr_destroy (&rwattr); if (result == 0) { rv = os_resultSuccess; } else { rv = os_resultFail; } return rv; }
int main(void) { pthread_rwlockattr_t rwla; int rc; /* Initialize a rwlock attributes object */ rc = pthread_rwlockattr_init(&rwla); if (rc != 0) { printf("Error at pthread_rwlockattr_init(), error code: %d\n", rc); return PTS_UNRESOLVED; } /* Destroy the rwlock attributes object */ rc = pthread_rwlockattr_destroy(&rwla); if (rc != 0) { printf ("Error at pthread_rwlockattr_destroy(), error code: %d\n", rc); printf("Test FAILED\n"); return PTS_FAIL; } printf("Test PASSED\n"); return PTS_PASS; }
/* The 'offset' parameter is optional, but must be provided to be able to use heap_remove(). * If heap_remove() will not be used, then a negative value can be provided. */ heap_t heap_new(int height, ssize_t offset, int cmp(const void *x, const void *y)) { heap_t heap; pthread_mutexattr_t attr; pthread_rwlockattr_t rwattr; if (height <= 0) height = 8; if (cmp == NULL) return NULL; if (NEW(heap) == NULL) return NULL; heap->avail = (height << 1) - 1; heap->curr = 0; if ((heap->h = CALLOC(1, heap->avail * sizeof *heap->h)) == NULL) { FREE(heap); return NULL; } heap->offset = offset; heap->cmp = cmp; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); pthread_mutex_init(&heap->lock, &attr); pthread_mutexattr_destroy(&attr); pthread_rwlockattr_init(&rwattr); pthread_rwlockattr_setkind_np(&rwattr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); pthread_rwlock_init(&heap->rwlock, &rwattr); pthread_rwlockattr_destroy(&rwattr); return heap; }
vp_lock_t *vp_lock_new(pthread_mutexattr_t *ma, pthread_condattr_t *ca) { vp_lock_t *l; #ifdef HAVE_PTHREAD_RWLOCKS pthread_rwlockattr_t attr; #endif l = calloc(1,sizeof(*l)); AN(l); l->magic = VP_LOCK_MAGIC; #ifndef HAVE_PTHREAD_RWLOCKS l->r = l->w = l->nw = 0; l->t = vp_lock_unset; AZ(pthread_mutex_init(&l->m,ma)); AZ(pthread_cond_init(&l->c,ca)); #else AZ(pthread_rwlockattr_init(&attr)); #ifdef HAVE_PTHREAD_RWLOCKATTR_SETPSHARED AZ(pthread_rwlockattr_setpshared(&attr,PTHREAD_PROCESS_PRIVATE)); #endif AZ(pthread_rwlock_init(&l->l,&attr)); AZ(pthread_rwlockattr_destroy(&attr)); #endif return l; }
int do_test (void) { xpthread_rwlockattr_init (&mylock_attr); xpthread_rwlockattr_setkind_np (&mylock_attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); xpthread_rwlock_init (&mylock, &mylock_attr); for (int n = 0; n < LOOPS; n++) { pthread_t tids[NTHREADS]; do_exit = 0; for (int i = 0; i < NTHREADS; i++) tids[i] = xpthread_create (NULL, run_loop, NULL); /* Let the threads run for some time. */ sleep (1); printf ("Exiting..."); fflush (stdout); do_exit = 1; for (int i = 0; i < NTHREADS; i++) xpthread_join (tids[i]); printf ("done.\n"); } pthread_rwlock_destroy (&mylock); pthread_rwlockattr_destroy (&mylock_attr); return 0; }
CRWLock::CRWLock() { pthread_rwlockattr_t rwlock_attr; int res; if((res = pthread_rwlockattr_init(&rwlock_attr)) != 0) { printf("file: "__FILE__", line: %d, " \ "call pthread_rwlockattr_init failed, err: %s\n", \ __LINE__, strerror(res)); throw res; } if((res = pthread_rwlockattr_setpshared(&rwlock_attr, \ PTHREAD_PROCESS_SHARED)) != 0) { printf("file: "__FILE__", line: %d, " \ "set rwlock attr to PTHREAD_PROCESS_SHARED failed, err: %s\n", \ __LINE__, strerror(res)); throw res; } if((res = pthread_rwlock_init(&m_rwlock, &rwlock_attr)) != 0) { printf("file: "__FILE__", line: %d, " \ "call pthread_rwlock_init failed, err: %s\n", \ __LINE__, strerror(res)); throw res; } pthread_rwlockattr_destroy(&rwlock_attr); }
int main() { int cnt = 0; pthread_rwlockattr_t rwlockattr; if(pthread_rwlockattr_init(&rwlockattr) != 0) { printf("Error at pthread_rwlockattr_init()\n"); return PTS_UNRESOLVED; } if(pthread_rwlock_init(&rwlock, &rwlockattr) != 0) { printf("Test FAILED: Error in pthread_rwlock_init()\n"); return PTS_FAIL; } while(cnt++ < COUNT) { if(pthread_rwlock_rdlock(&rwlock) != 0) { printf("Test FAILED: cannot get read lock on %dth loop\n", cnt); return PTS_FAIL; } if(pthread_rwlock_unlock(&rwlock) != 0) { printf("Test FAILED: cannot release read lock on %dth loop\n", cnt); return PTS_FAIL; } if(pthread_rwlock_wrlock(&rwlock) != 0) { printf("Test FAILED: cannot get write lock on %dth loop\n", cnt); return PTS_FAIL; } if(pthread_rwlock_unlock(&rwlock) != 0) { printf("Test FAILED: cannot release write lock on %dth loop\n", cnt); return PTS_FAIL; } } if(pthread_rwlock_destroy(&rwlock) != 0) { printf("Error at pthread_rwlockattr_destroy()\n"); return PTS_UNRESOLVED; } if(pthread_rwlockattr_destroy(&rwlockattr) != 0) { printf("Error at pthread_rwlockattr_destroy()\n"); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; }
CUserQueryWorkThreads::~CUserQueryWorkThreads() { // TODO Auto-generated destructor stub pthread_rwlock_destroy(&p_rwlock); pthread_rwlockattr_destroy(&p_rwlock_attr); if(m_vecTaskBuf[m_uiThreadId]) { delete m_vecTaskBuf[m_uiThreadId]; } }
RWLock::RWLock(string name_): rwname(name_) { pthread_rwlockattr_t attr; pthread_rwlockattr_init(&attr); pthread_rwlock_init(&rwlock, &attr); pthread_rwlockattr_destroy(&attr); }
CRWLock::CRWLock() { pthread_rwlockattr_t attr; pthread_rwlockattr_init( &attr ); //写锁优先,一旦有写锁去请求,后续所有的读锁请求都会阻塞,即使已经有线程获取了读锁也如此 pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); pthread_rwlock_init(&_rwlock,&attr); pthread_rwlockattr_destroy(&attr); }
CRWMutex::~CRWMutex() { #ifndef ANDROID pthread_rwlock_destroy(&mMutex); pthread_rwlockattr_destroy(&mAttr); #else rwlock_deinit(&mMutex); #endif //ANDROID }
static int my_pthread_rwlockattr_destroy(pthread_rwlockattr_t *__attr) { int ret; pthread_rwlockattr_t *realattr = (pthread_rwlockattr_t *) *(unsigned int *) __attr; ret = pthread_rwlockattr_destroy(realattr); free(realattr); return ret; }
ReadWriteLock::~ReadWriteLock() { #ifdef TARGET_OS_WINDOWS CloseHandle(rdgreen); CloseHandle(wrgreen); DeleteCriticalSection(&rwcs); #else pthread_rwlock_destroy(&m_rwlock); pthread_rwlockattr_destroy(&m_rwlockAttr); #endif }
static int do_test (void) { size_t cnt; for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt) { pthread_rwlock_t r; pthread_rwlockattr_t a; if (pthread_rwlockattr_init (&a) != 0) FAIL_EXIT1 ("round %Zu: rwlockattr_t failed\n", cnt); if (pthread_rwlockattr_setkind_np (&a, kind[cnt]) != 0) FAIL_EXIT1 ("round %Zu: rwlockattr_setkind failed\n", cnt); if (pthread_rwlock_init (&r, &a) != 0) FAIL_EXIT1 ("round %Zu: rwlock_init failed\n", cnt); if (pthread_rwlockattr_destroy (&a) != 0) FAIL_EXIT1 ("round %Zu: rwlockattr_destroy failed\n", cnt); struct timespec ts; xclock_gettime (CLOCK_REALTIME, &ts); ++ts.tv_sec; /* Get a read lock. */ if (pthread_rwlock_timedrdlock (&r, &ts) != 0) FAIL_EXIT1 ("round %Zu: rwlock_timedrdlock failed\n", cnt); printf ("%zu: got timedrdlock\n", cnt); pthread_t th; if (pthread_create (&th, NULL, tf, &r) != 0) FAIL_EXIT1 ("round %Zu: create failed\n", cnt); void *status; if (pthread_join (th, &status) != 0) FAIL_EXIT1 ("round %Zu: join failed\n", cnt); if (status != NULL) FAIL_EXIT1 ("failure in round %Zu\n", cnt); if (pthread_rwlock_destroy (&r) != 0) FAIL_EXIT1 ("round %Zu: rwlock_destroy failed\n", cnt); } return 0; }
qp_rwlock_t qp_rwlock_create(qp_rwlock_t rwlock, bool shared) { pthread_rwlockattr_t attr; if (NULL == rwlock) { rwlock = (qp_rwlock_t)qp_alloc(sizeof(struct qp_ipc_rwlock_s)); if (NULL == rwlock) { return NULL; } memset(rwlock, 0, sizeof(struct qp_ipc_rwlock_s)); qp_rwlock_set_alloced(rwlock); } else { memset(rwlock, 0, sizeof(struct qp_ipc_rwlock_s)); } if (QP_SUCCESS != pthread_rwlockattr_init(&attr)) { qp_rwlock_is_alloced(rwlock) ? qp_free(rwlock) : 1; return NULL; } #ifdef _POSIX_THREAD_PROCESS_SHARED if (shared) { if (QP_SUCCESS != pthread_rwlockattr_setpshared(&attr, \ PTHREAD_PROCESS_SHARED)) { qp_rwlock_is_alloced(rwlock) ? qp_free(rwlock) : 1; return NULL; } qp_rwlock_set_shared(rwlock); } #endif if (QP_SUCCESS != pthread_rwlock_init(&(rwlock->rwlock), &attr)) { qp_rwlock_is_alloced(rwlock) ? qp_free(rwlock) : 1; return NULL; } pthread_rwlockattr_destroy(&attr); qp_rwlock_set_inited(rwlock); return rwlock; }
void gdnsd_prcu_setup_lock(void) { int pthread_err; pthread_rwlockattr_t lockatt; if((pthread_err = pthread_rwlockattr_init(&lockatt))) log_fatal("pthread_rwlockattr_init() failed: %s", dmn_logf_strerror(pthread_err)); // Non-portable way to boost writer priority. Our writelocks are held very briefly // and very rarely, whereas the readlocks could be very spammy, and we don't want to // block the write operation forever. This works on Linux+glibc. # ifdef PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP if((pthread_err = pthread_rwlockattr_setkind_np(&lockatt, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))) log_fatal("pthread_rwlockattr_setkind_np(PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) failed: %s", dmn_logf_strerror(pthread_err)); # endif if((pthread_err = pthread_rwlock_init(&gdnsd_prcu_rwlock, &lockatt))) log_fatal("pthread_rwlock_init() failed: %s", dmn_logf_strerror(pthread_err)); if((pthread_err = pthread_rwlockattr_destroy(&lockatt))) log_fatal("pthread_rwlockattr_destroy() failed: %s", dmn_logf_strerror(pthread_err)); }
/** * Allocate a new Video mixer * * @param mixp Pointer to allocated video mixer * * @return 0 for success, otherwise error code */ int vidmix_alloc(struct vidmix **mixp) { pthread_rwlockattr_t attr; struct vidmix *mix; int err; if (!mixp) return EINVAL; mix = mem_zalloc(sizeof(*mix), destructor); if (!mix) return ENOMEM; err = pthread_rwlockattr_init(&attr); if (err) { mem_deref(mix); return err; } #if defined(LINUX) && defined(__GLIBC__) err = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); if (err) goto out; #endif err = pthread_rwlock_init(&mix->rwlock, &attr); if (err) goto out; mix->initialized = true; out: (void)pthread_rwlockattr_destroy(&attr); if (err) mem_deref(mix); else *mixp = mix; return err; }
process_cache::process_cache(size_t m) : memsize(m) { pthread_mutexattr_t a; pthread_rwlockattr_t al; if( pthread_mutexattr_init(&a) || pthread_mutexattr_setpshared(&a,PTHREAD_PROCESS_SHARED) || pthread_mutex_init(&lru_mutex,&a) || pthread_mutexattr_destroy(&a) || pthread_rwlockattr_init(&al) || pthread_rwlockattr_setpshared(&al,PTHREAD_PROCESS_SHARED) || pthread_rwlock_init(&access_lock,&al) || pthread_rwlockattr_destroy(&al)) { throw cppcms_error(errno,"Failed setup mutexes --- is this system " "supports process shared mutex/rwlock?"); } };
static void init_read_write_lock(pthread_rwlock_t* lock) { pthread_rwlockattr_t* pattr; #if defined(YOG_HAVE_PTHREAD_RWLOCKATTR_INIT) pthread_rwlockattr_t attr; pthread_rwlockattr_init(&attr); # if defined(YOG_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NP); # endif pattr = &attr; #else pattr = NULL; #endif int err; if ((err = pthread_rwlock_init(lock, pattr)) != 0) { YOG_BUG(NULL, "pthread_rwlock_init failed: %s", strerror(err)); } #if defined(YOG_HAVE_PTHREAD_RWLOCKATTR_INIT) && defined(YOG_HAVE_PTHREAD_RWLOCKATTR_DESTROY) pthread_rwlockattr_destroy(&attr); #endif }
TEST(pthread, pthread_rwlockattr_smoke) { pthread_rwlockattr_t attr; ASSERT_EQ(0, pthread_rwlockattr_init(&attr)); int pshared_value_array[] = {PTHREAD_PROCESS_PRIVATE, PTHREAD_PROCESS_SHARED}; for (size_t i = 0; i < sizeof(pshared_value_array) / sizeof(pshared_value_array[0]); ++i) { ASSERT_EQ(0, pthread_rwlockattr_setpshared(&attr, pshared_value_array[i])); int pshared; ASSERT_EQ(0, pthread_rwlockattr_getpshared(&attr, &pshared)); ASSERT_EQ(pshared_value_array[i], pshared); } int kind_array[] = {PTHREAD_RWLOCK_PREFER_READER_NP, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP}; for (size_t i = 0; i < sizeof(kind_array) / sizeof(kind_array[0]); ++i) { ASSERT_EQ(0, pthread_rwlockattr_setkind_np(&attr, kind_array[i])); int kind; ASSERT_EQ(0, pthread_rwlockattr_getkind_np(&attr, &kind)); ASSERT_EQ(kind_array[i], kind); } ASSERT_EQ(0, pthread_rwlockattr_destroy(&attr)); }
int main(void) { pthread_rwlockattr_t rwla; int pshared; #ifndef PTHREAD_PROCESS_SHARED printf("process-shared attribute is not available for testing\n"); return PTS_UNSUPPORTED; #endif /* Initialize a rwlock attributes object */ if (pthread_rwlockattr_init(&rwla) != 0) { printf("Error at pthread_rwlockattr_init()\n"); return PTS_UNRESOLVED; } /* The default 'pshared' attribute should be PTHREAD_PROCESS_PRIVATE */ if (pthread_rwlockattr_getpshared(&rwla, &pshared) != 0) { printf("Error at pthread_rwlockattr_getpshared()\n"); return PTS_UNRESOLVED; } if (pshared != PTHREAD_PROCESS_PRIVATE) { printf("Test FAILED: Incorrect default pshared value: %d\n", pshared); return PTS_FAIL; } /* Cleanup */ if ((pthread_rwlockattr_destroy(&rwla)) != 0) { printf("Error at pthread_rwlockattr_destroy()\n"); return PTS_UNRESOLVED; } printf("Test PASSED\n"); return PTS_PASS; }
struct hash_table * hashtable_init(struct hash_param *hparam) { /* The hash table being constructed */ struct hash_table *ht = NULL; /* The index for initializing each partition */ uint32_t index = 0; /* Read-Write Lock attributes, to prevent write starvation under GLIBC */ pthread_rwlockattr_t rwlockattr; /* Hash partition */ struct hash_partition *partition = NULL; /* The number of fully initialized partitions */ uint32_t completed = 0; if (pthread_rwlockattr_init(&rwlockattr) != 0) return NULL; /* At some point factor this out into the OS directory. it is necessary to prevent writer starvation under GLIBC. */ #ifdef GLIBC if ((pthread_rwlockattr_setkind_np (&rwlockattrs, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)) != 0) { LogCrit(COMPONENT_HASHTABLE, "Unable to set writer-preference on lock attribute."); goto deconstruct; } #endif /* GLIBC */ ht = gsh_calloc(1, sizeof(struct hash_table) + (sizeof(struct hash_partition) * hparam->index_size)); /* Fixup entry size */ if (hparam->flags & HT_FLAG_CACHE) { if (!hparam->cache_entry_count) /* works fine with a good hash algo */ hparam->cache_entry_count = 32767; } /* We need to save copy of the parameters in the table. */ ht->parameter = *hparam; for (index = 0; index < hparam->index_size; ++index) { partition = (&ht->partitions[index]); RBT_HEAD_INIT(&(partition->rbt)); if (pthread_rwlock_init(&partition->lock, &rwlockattr) != 0) { LogCrit(COMPONENT_HASHTABLE, "Unable to initialize lock in hash table."); goto deconstruct; } /* Allocate a cache if requested */ if (hparam->flags & HT_FLAG_CACHE) partition->cache = gsh_calloc(1, cache_page_size(ht)); completed++; } ht->node_pool = pool_basic_init(NULL, sizeof(rbt_node_t)); ht->data_pool = pool_basic_init(NULL, sizeof(struct hash_data)); pthread_rwlockattr_destroy(&rwlockattr); return ht; deconstruct: while (completed != 0) { if (hparam->flags & HT_FLAG_CACHE) gsh_free(ht->partitions[completed - 1].cache); PTHREAD_RWLOCK_destroy(&(ht->partitions[completed - 1].lock)); completed--; } if (ht->node_pool) pool_destroy(ht->node_pool); if (ht->data_pool) pool_destroy(ht->data_pool); gsh_free(ht); return ht = NULL; }
static int do_test (void) { pthread_rwlock_t r; pthread_rwlockattr_t at; int e; if (pthread_rwlockattr_init (&at) != 0) { puts ("rwlockattr_init failed"); return 1; } puts ("rwlockattr_init succeeded"); #ifndef TYPE # define TYPE PTHREAD_RWLOCK_PREFER_READER_NP #endif if (pthread_rwlockattr_setkind_np (&at, TYPE) != 0) { puts ("rwlockattr_setkind failed"); return 1; } puts ("rwlockattr_setkind succeeded"); if (pthread_rwlock_init (&r, &at) != 0) { puts ("rwlock_init failed"); return 1; } puts ("rwlock_init succeeded"); if (pthread_rwlockattr_destroy (&at) != 0) { puts ("rwlockattr_destroy failed"); return 1; } puts ("rwlockattr_destroy succeeded"); if (pthread_rwlock_wrlock (&r) != 0) { puts ("1st rwlock_wrlock failed"); return 1; } puts ("1st rwlock_wrlock succeeded"); e = pthread_rwlock_tryrdlock (&r); if (e == 0) { puts ("rwlock_tryrdlock on rwlock with writer succeeded"); return 1; } if (e != EBUSY) { puts ("rwlock_tryrdlock on rwlock with writer return value != EBUSY"); return 1; } puts ("rwlock_tryrdlock on rwlock with writer failed with EBUSY"); e = pthread_rwlock_trywrlock (&r); if (e == 0) { puts ("rwlock_trywrlock on rwlock with writer succeeded"); return 1; } if (e != EBUSY) { puts ("rwlock_trywrlock on rwlock with writer return value != EBUSY"); return 1; } puts ("rwlock_trywrlock on rwlock with writer failed with EBUSY"); if (pthread_rwlock_unlock (&r) != 0) { puts ("1st rwlock_unlock failed"); return 1; } puts ("1st rwlock_unlock succeeded"); if (pthread_rwlock_tryrdlock (&r) != 0) { puts ("rwlock_tryrdlock on unlocked rwlock failed"); return 1; } puts ("rwlock_tryrdlock on unlocked rwlock succeeded"); e = pthread_rwlock_trywrlock (&r); if (e == 0) { puts ("rwlock_trywrlock on rwlock with reader succeeded"); return 1; } if (e != EBUSY) { puts ("rwlock_trywrlock on rwlock with reader return value != EBUSY"); return 1; } puts ("rwlock_trywrlock on rwlock with reader failed with EBUSY"); if (pthread_rwlock_unlock (&r) != 0) { puts ("2nd rwlock_unlock failed"); return 1; } puts ("2nd rwlock_unlock succeeded"); if (pthread_rwlock_trywrlock (&r) != 0) { puts ("rwlock_trywrlock on unlocked rwlock failed"); return 1; } puts ("rwlock_trywrlock on unlocked rwlock succeeded"); e = pthread_rwlock_tryrdlock (&r); if (e == 0) { puts ("rwlock_tryrdlock on rwlock with writer succeeded"); return 1; } if (e != EBUSY) { puts ("rwlock_tryrdlock on rwlock with writer return value != EBUSY"); return 1; } puts ("rwlock_tryrdlock on rwlock with writer failed with EBUSY"); if (pthread_rwlock_unlock (&r) != 0) { puts ("3rd rwlock_unlock failed"); return 1; } puts ("3rd rwlock_unlock succeeded"); if (pthread_rwlock_destroy (&r) != 0) { puts ("rwlock_destroy failed"); return 1; } puts ("rwlock_destroy succeeded"); return 0; }