static int squash_stream_thread_func (SquashStream* stream) { assert (stream != NULL); SquashStreamPrivate* priv = stream->priv; SquashOperation operation; SquashCodec* codec = stream->codec; assert (priv != NULL); assert (codec != NULL); mtx_lock (&(priv->io_mtx)); priv->result = SQUASH_OK; cnd_signal (&(priv->result_cnd)); while ((operation = priv->request) == SQUASH_OPERATION_INVALID) { cnd_wait (&(priv->request_cnd), &(priv->io_mtx)); } priv->request = SQUASH_OPERATION_INVALID; assert (codec->impl.splice != NULL); priv->result = codec->impl.splice (codec, stream->options, stream->stream_type, squash_stream_read_cb, squash_stream_write_cb, stream); if (priv->result == SQUASH_OK) priv->result = SQUASH_END_OF_STREAM; priv->finished = true; cnd_signal (&(priv->result_cnd)); mtx_unlock (&(priv->io_mtx)); return 0; }
static int physics_thread_main(void* arg) { GLFWwindow* window = arg; for (;;) { mtx_lock(&thread_sync.particles_lock); // Wait for particle drawing to be done while (!glfwWindowShouldClose(window) && thread_sync.p_frame > thread_sync.d_frame) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_nsec += 100000000; cnd_timedwait(&thread_sync.d_done, &thread_sync.particles_lock, &ts); } if (glfwWindowShouldClose(window)) break; // Update particles particle_engine(thread_sync.t, thread_sync.dt); // Update frame counter thread_sync.p_frame++; // Unlock mutex and signal drawing thread mtx_unlock(&thread_sync.particles_lock); cnd_signal(&thread_sync.p_done); } return 0; }
void db_insert_block(int p, int q, int x, int y, int z, int w) { if (!db_enabled) { return; } mtx_lock(&mtx); ring_put_block(&ring, p, q, x, y, z, w); cnd_signal(&cnd); mtx_unlock(&mtx); }
/* ==================== HandleMessage ==================== */ static void HandleMessage( const void *const arg ) { const server_message_t message = *( server_message_t * )arg; ServerInit( message.ip_socket, message.ip6_socket ); mtx_lock( &server_mutex ); mtx_unlock( &server_mutex ); cnd_signal( &server_condition ); }
void db_set_key(int p, int q, int key) { if (!db_enabled) { return; } mtx_lock(&mtx); ring_put_key(&ring, p, q, key); cnd_signal(&cnd); mtx_unlock(&mtx); }
void db_commit() { if (!db_enabled) { return; } mtx_lock(&mtx); ring_put_commit(&ring); cnd_signal(&cnd); mtx_unlock(&mtx); }
int stack10_push(Stack10 *s, int x){ mtx_lock(&s->mtx_); while(s->vused_ >= S_SIZE){ cnd_wait(&s->cnd_push_, &s->mtx_); } s->v_[s->vused_++] = x; cnd_signal(&s->cnd_pop_); mtx_unlock(&s->mtx_); return 0; }
int stack10_pop(Stack10 *s, int *x){ mtx_lock(&s->mtx_); while(s->vused_ == 0){ cnd_wait(&s->cnd_pop_, &s->mtx_); } *x = s->v_[--s->vused_]; cnd_signal(&s->cnd_push_); mtx_unlock(&s->mtx_); return 0; }
enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring, struct util_packet *packet, unsigned max_dwords, boolean wait ) { const struct util_packet *ring_packet; unsigned i; int ret = PIPE_OK; /* XXX: over-reliance on mutexes, etc: */ mtx_lock(&ring->mutex); /* Get next ring entry: */ if (wait) { while (util_ringbuffer_empty(ring)) cnd_wait(&ring->change, &ring->mutex); } else { if (util_ringbuffer_empty(ring)) { ret = PIPE_ERROR_OUT_OF_MEMORY; goto out; } } ring_packet = &ring->buf[ring->tail]; /* Both of these are considered bugs. Raise an assert on debug builds. */ if (ring_packet->dwords > ring->mask + 1 - util_ringbuffer_space(ring) || ring_packet->dwords > max_dwords) { assert(0); ret = PIPE_ERROR_BAD_INPUT; goto out; } /* Copy data from ring: */ for (i = 0; i < ring_packet->dwords; i++) { packet[i] = ring->buf[ring->tail]; ring->tail++; ring->tail &= ring->mask; } out: /* Signal change: */ cnd_signal(&ring->change); mtx_unlock(&ring->mutex); return ret; }
void db_worker_stop() { if (!db_enabled) { return; } mtx_lock(&mtx); ring_put_exit(&ring); cnd_signal(&cnd); mtx_unlock(&mtx); thrd_join(thrd, NULL); cnd_destroy(&cnd); mtx_destroy(&mtx); ring_free(&ring); }
void push_synclist(SyncTileList* list,Tile* tile) { TileNode* node = (TileNode*)malloc(sizeof(TileNode)); node->tile = tile; node->next=0; node->prev=0; mtx_lock(&list->mtx); // call from main thread.. if (list->last==0) { list->first = node; list->last = node; } else { list->last->next = node; node->prev = list->last; list->last = node; } ++list->count; mtx_unlock(&list->mtx); cnd_signal(&list->cnd); }
static void rd_kafka_timer_schedule (rd_kafka_timers_t *rkts, rd_kafka_timer_t *rtmr, int extra_us) { rd_kafka_timer_t *first; /* Timer has been stopped */ if (!rtmr->rtmr_interval) return; rtmr->rtmr_next = rd_clock() + rtmr->rtmr_interval + extra_us; if (!(first = TAILQ_FIRST(&rkts->rkts_timers)) || first->rtmr_next > rtmr->rtmr_next) { TAILQ_INSERT_HEAD(&rkts->rkts_timers, rtmr, rtmr_link); cnd_signal(&rkts->rkts_cond); } else TAILQ_INSERT_SORTED(&rkts->rkts_timers, rtmr, rd_kafka_timer_s, rtmr_link, rd_kafka_timer_cmp); }
static SquashStatus squash_stream_send_to_thread (SquashStream* stream, SquashOperation operation) { SquashStreamPrivate* priv = stream->priv; SquashStatus result; priv->request = operation; cnd_signal (&(priv->request_cnd)); mtx_unlock (&(priv->io_mtx)); mtx_lock (&(priv->io_mtx)); while ((result = priv->result) == SQUASH_STATUS_INVALID) { cnd_wait (&(priv->result_cnd), &(priv->io_mtx)); } priv->result = SQUASH_STATUS_INVALID; if (priv->finished == true) { mtx_unlock (&(priv->io_mtx)); thrd_join (priv->thread, NULL); } return result; }
/** * @brief Yield execution back to the main thread * @protected * * This function may only be called inside the processing thread * spawned for thread-based plugins. * * @param stream The stream * @param status Status code to return for the current request * @return The code of the next requested operation */ static SquashOperation squash_stream_yield (SquashStream* stream, SquashStatus status) { SquashStreamPrivate* priv = stream->priv; SquashOperation operation; assert (stream != NULL); assert (priv != NULL); priv->request = SQUASH_OPERATION_INVALID; priv->result = status; cnd_signal (&(priv->result_cnd)); mtx_unlock (&(priv->io_mtx)); if (status < 0) thrd_exit (status); mtx_lock (&(priv->io_mtx)); while ((operation = priv->request) == SQUASH_OPERATION_INVALID) { cnd_wait (&(priv->request_cnd), &(priv->io_mtx)); } return operation; }
static int ctrl_thrd_main (void *arg) { mtx_lock(&ctrl.lock); while (!ctrl.term) { int64_t now; cnd_timedwait_ms(&ctrl.cnd, &ctrl.lock, 10); if (ctrl.cmd.ts_at) { ctrl.next.ts_at = ctrl.cmd.ts_at; ctrl.next.delay = ctrl.cmd.delay; ctrl.cmd.ts_at = 0; ctrl.cmd.ack = 1; printf(_C_CYA "## %s: sockem: " "receieved command to set delay " "to %d in %dms\n" _C_CLR, __FILE__, ctrl.next.delay, (int)(ctrl.next.ts_at - test_clock()) / 1000); } now = test_clock(); if (ctrl.next.ts_at && now > ctrl.next.ts_at) { assert(ctrl.skm); printf(_C_CYA "## %s: " "sockem: setting socket delay to %d\n" _C_CLR, __FILE__, ctrl.next.delay); sockem_set(ctrl.skm, "delay", ctrl.next.delay, NULL); ctrl.next.ts_at = 0; cnd_signal(&ctrl.cnd); /* signal back to caller */ } } mtx_unlock(&ctrl.lock); return 0; }
bool RWMutex::unlock() { bool result1 = true, result2 = true; if(nExclusiveAccessCount == 0) { if(mtx_lock(&mtxSharedAccessCompleted) != thrd_success) return false; // nCompletedSharedAccessCount++; if(++nCompletedSharedAccessCount == 0) { result1 = (cnd_signal(&cndSharedAccessCompleted) == thrd_success); } result2 = (mtx_unlock(&mtxSharedAccessCompleted) == thrd_success); } else { nExclusiveAccessCount--; result1 = (mtx_unlock(&mtxSharedAccessCompleted) == thrd_success); result2 = (mtx_unlock(&mtxExclusiveAccess) == thrd_success); } return (result1 && result2); }
void util_ringbuffer_enqueue( struct util_ringbuffer *ring, const struct util_packet *packet ) { unsigned i; /* XXX: over-reliance on mutexes, etc: */ mtx_lock(&ring->mutex); /* make sure we don't request an impossible amount of space */ assert(packet->dwords <= ring->mask); /* Wait for free space: */ while (util_ringbuffer_space(ring) < packet->dwords) cnd_wait(&ring->change, &ring->mutex); /* Copy data to ring: */ for (i = 0; i < packet->dwords; i++) { /* Copy all dwords of the packet. Note we're abusing the * typesystem a little - we're being passed a pointer to * something, but probably not an array of packet structs: */ ring->buf[ring->head] = packet[i]; ring->head++; ring->head &= ring->mask; } /* Signal change: */ cnd_signal(&ring->change); mtx_unlock(&ring->mutex); }
static void draw_particles(GLFWwindow* window, double t, float dt) { int i, particle_count; Vertex vertex_array[BATCH_PARTICLES * PARTICLE_VERTS]; Vertex* vptr; float alpha; GLuint rgba; Vec3 quad_lower_left, quad_lower_right; GLfloat mat[16]; PARTICLE* pptr; // Here comes the real trick with flat single primitive objects (s.c. // "billboards"): We must rotate the textured primitive so that it // always faces the viewer (is coplanar with the view-plane). // We: // 1) Create the primitive around origo (0,0,0) // 2) Rotate it so that it is coplanar with the view plane // 3) Translate it according to the particle position // Note that 1) and 2) is the same for all particles (done only once). // Get modelview matrix. We will only use the upper left 3x3 part of // the matrix, which represents the rotation. glGetFloatv(GL_MODELVIEW_MATRIX, mat); // 1) & 2) We do it in one swift step: // Although not obvious, the following six lines represent two matrix/ // vector multiplications. The matrix is the inverse 3x3 rotation // matrix (i.e. the transpose of the same matrix), and the two vectors // represent the lower left corner of the quad, PARTICLE_SIZE/2 * // (-1,-1,0), and the lower right corner, PARTICLE_SIZE/2 * (1,-1,0). // The upper left/right corners of the quad is always the negative of // the opposite corners (regardless of rotation). quad_lower_left.x = (-PARTICLE_SIZE / 2) * (mat[0] + mat[1]); quad_lower_left.y = (-PARTICLE_SIZE / 2) * (mat[4] + mat[5]); quad_lower_left.z = (-PARTICLE_SIZE / 2) * (mat[8] + mat[9]); quad_lower_right.x = (PARTICLE_SIZE / 2) * (mat[0] - mat[1]); quad_lower_right.y = (PARTICLE_SIZE / 2) * (mat[4] - mat[5]); quad_lower_right.z = (PARTICLE_SIZE / 2) * (mat[8] - mat[9]); // Don't update z-buffer, since all particles are transparent! glDepthMask(GL_FALSE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Select particle texture if (!wireframe) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, particle_tex_id); } // Set up vertex arrays. We use interleaved arrays, which is easier to // handle (in most situations) and it gives a linear memeory access // access pattern (which may give better performance in some // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, // 4 ubytes for color and 3 floats for vertex coord (in that order). // Most OpenGL cards / drivers are optimized for this format. glInterleavedArrays(GL_T2F_C4UB_V3F, 0, vertex_array); // Wait for particle physics thread to be done mtx_lock(&thread_sync.particles_lock); while (!glfwWindowShouldClose(window) && thread_sync.p_frame <= thread_sync.d_frame) { struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); ts.tv_nsec += 100000000; cnd_timedwait(&thread_sync.p_done, &thread_sync.particles_lock, &ts); } // Store the frame time and delta time for the physics thread thread_sync.t = t; thread_sync.dt = dt; // Update frame counter thread_sync.d_frame++; // Loop through all particles and build vertex arrays. particle_count = 0; vptr = vertex_array; pptr = particles; for (i = 0; i < MAX_PARTICLES; i++) { if (pptr->active) { // Calculate particle intensity (we set it to max during 75% // of its life, then it fades out) alpha = 4.f * pptr->life; if (alpha > 1.f) alpha = 1.f; // Convert color from float to 8-bit (store it in a 32-bit // integer using endian independent type casting) ((GLubyte*) &rgba)[0] = (GLubyte)(pptr->r * 255.f); ((GLubyte*) &rgba)[1] = (GLubyte)(pptr->g * 255.f); ((GLubyte*) &rgba)[2] = (GLubyte)(pptr->b * 255.f); ((GLubyte*) &rgba)[3] = (GLubyte)(alpha * 255.f); // 3) Translate the quad to the correct position in modelview // space and store its parameters in vertex arrays (we also // store texture coord and color information for each vertex). // Lower left corner vptr->s = 0.f; vptr->t = 0.f; vptr->rgba = rgba; vptr->x = pptr->x + quad_lower_left.x; vptr->y = pptr->y + quad_lower_left.y; vptr->z = pptr->z + quad_lower_left.z; vptr ++; // Lower right corner vptr->s = 1.f; vptr->t = 0.f; vptr->rgba = rgba; vptr->x = pptr->x + quad_lower_right.x; vptr->y = pptr->y + quad_lower_right.y; vptr->z = pptr->z + quad_lower_right.z; vptr ++; // Upper right corner vptr->s = 1.f; vptr->t = 1.f; vptr->rgba = rgba; vptr->x = pptr->x - quad_lower_left.x; vptr->y = pptr->y - quad_lower_left.y; vptr->z = pptr->z - quad_lower_left.z; vptr ++; // Upper left corner vptr->s = 0.f; vptr->t = 1.f; vptr->rgba = rgba; vptr->x = pptr->x - quad_lower_right.x; vptr->y = pptr->y - quad_lower_right.y; vptr->z = pptr->z - quad_lower_right.z; vptr ++; // Increase count of drawable particles particle_count ++; } // If we have filled up one batch of particles, draw it as a set // of quads using glDrawArrays. if (particle_count >= BATCH_PARTICLES) { // The first argument tells which primitive type we use (QUAD) // The second argument tells the index of the first vertex (0) // The last argument is the vertex count glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); particle_count = 0; vptr = vertex_array; } // Next particle pptr++; } // We are done with the particle data mtx_unlock(&thread_sync.particles_lock); cnd_signal(&thread_sync.d_done); // Draw final batch of particles (if any) glDrawArrays(GL_QUADS, 0, PARTICLE_VERTS * particle_count); // Disable vertex arrays (Note: glInterleavedArrays implicitly called // glEnableClientState for vertex, texture coord and color arrays) glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDepthMask(GL_TRUE); }
int NetProbeServerTP(char *TCPPort, char *threadnum){ //Create a thread pool cnd_init(&cond); mtx_init(&ThMutex, mtx_plain); int ThreadNum = atoi(threadnum); for (int j = 0; j < ThreadNum; j++){ thrd_t TCPSThread; if (thrd_create(&TCPSThread, TPTCPChild, NULL) == thrd_error){ printf("Create thread is failed\n"); return 0; } else{ printf("Creating thread %d in threadpool mode.\n", j+1); if (j == ThreadNum-1){ printf("Create threadpool with %d threads in totoal.\n", j+1); printf("Waiting for client to connect...\n"); } } } SOCKET Socket, new_socket; struct sockaddr_in server, client; int recv_len; socklen_t c; c = sizeof(struct sockaddr_in); char *ReceiveBuf; ReceiveBuf = (char *)malloc(sizeof(char)* 1024); //Initialize Winsock #ifdef WIN32 WSADATA wsa; if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0){ printf("Failed to Initialize, Error code : %d", WSAGetLastError()); exit(EXIT_FAILURE); } #endif if ((Socket = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET){ printf("Could not create socket : d%", WSAGetLastError()); } memset(&server, 0, sizeof(struct sockaddr_in)); memset(&client, 0, sizeof(struct sockaddr_in)); server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(atoi(TCPPort)); if (bind(Socket, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR){ printf("Bind failed with error code : %d", WSAGetLastError()); exit(EXIT_FAILURE); } listen(Socket, 100); //Listening to new TCP connection while (1){ memset(ReceiveBuf, 0, 1024); if ((new_socket = accept(Socket, (struct sockaddr *)&client, &c)) == INVALID_SOCKET){ printf("accept failed with error code: %d\n", WSAGetLastError()); return 0; } else{ mtx_lock(&ThMutex); SocketQueue.Enqueue(&SocketQueue, new_socket); mtx_unlock(&ThMutex); cnd_signal(&cond); } Sleep(2); } closesocket(Socket); #ifdef WIN32 WSACleanup(); #endif return 0; }
/** * Interrupt rd_kafka_timers_run(). * Used for termination. */ void rd_kafka_timers_interrupt (rd_kafka_timers_t *rkts) { rd_kafka_timers_lock(rkts); cnd_signal(&rkts->rkts_cond); rd_kafka_timers_unlock(rkts); }
int main(int argc, char** argv) { signal(SIGINT, IntHandler); Server serv; // Initialize the server InitConfig(&serv.conf, argv[1], argc, argv); if(!serv.conf.name) { fprintf(stderr, "Script doesn't specify a server name.\n"); return 1; } if(!serv.conf.port) { fprintf(stderr, "Script doesn't specify a port.\n"); return 1; } printf("Successfully configured server.\n" "Name: %s\n" "Port: %s\n" "Num Threads: %d\n" "Cycles Per Loop: %d\n" "Num Routes: %d\n", serv.conf.name, serv.conf.port, serv.conf.numThreads, serv.conf.cyclesPerLoop, sb_count(serv.conf.routes)); InitList(&serv.clientQueue, sizeof(Sock)); InitList(&serv.requestQueue, sizeof(ClientRequest)); cnd_init(&serv.updateLoop); cnd_init(&serv.newConn); // The loop thread is responsible for initializing LoopData thrd_t loopThread, connThread; thrd_create(&loopThread, MainLoop, &serv); thrd_create(&connThread, ConnLoop, &serv); // Initialize winsock and listen for clients WSADATA wsaData; SOCKET listenSocket; int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if(iResult != 0) { fprintf(stderr, "WSAStartup failed: %d\n", iResult); return 1; } struct addrinfo hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; struct addrinfo* result; iResult = getaddrinfo(NULL, serv.conf.port, &hints, &result); if(iResult != 0) { fprintf(stderr, "getaddrinfo failed: %d\n", iResult); WSACleanup(); return 1; } listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if(listenSocket == INVALID_SOCKET) { fprintf(stderr, "Error at socket(): %d\n", WSAGetLastError()); freeaddrinfo(result); WSACleanup(); return 1; } freeaddrinfo(result); iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen); if(iResult == SOCKET_ERROR) { fprintf(stderr, "bind failed with error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); return 1; } if(listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) { fprintf(stderr, "listen failed with error: %d\n", WSAGetLastError()); closesocket(listenSocket); WSACleanup(); return 1; } while (KeepRunning) { SOCKET clientSocket = accept(listenSocket, NULL, NULL); if (clientSocket == INVALID_SOCKET) { fprintf(stderr, "accept failed: %d\n", WSAGetLastError()); continue; } int iMode = 1; if (ioctlsocket(clientSocket, FIONBIO, &iMode) == SOCKET_ERROR) { fprintf(stderr, "ioctlsocket failed: %d\n", WSAGetLastError()); continue; } Sock sock; InitSock(&sock, (void*)clientSocket); ListPushBack(&serv.clientQueue, &sock); cnd_signal(&serv.newConn); } WSACleanup(); thrd_join(&connThread, NULL); thrd_join(&loopThread, NULL); cnd_destroy(&serv.newConn); cnd_destroy(&serv.updateLoop); DestroyList(&serv.requestQueue); DestroyList(&serv.clientQueue); DestroyConfig(&serv.conf); return 0; }