DirectResult fusion_skirmish_init2( FusionSkirmish *skirmish, const char *name, const FusionWorld *world, bool local ) { D_ASSERT( skirmish != NULL ); D_ASSERT( name != NULL ); D_MAGIC_ASSERT( world, FusionWorld ); D_DEBUG_AT( Fusion_Skirmish, "fusion_skirmish_init2( %p, '%s', %s )\n", skirmish, name ? : "", local ? "local" : "shared" ); if (!local) return fusion_skirmish_init( skirmish, name, world ); skirmish->single = D_CALLOC( 1, sizeof(FusionSkirmishSingle) + strlen(name) + 1 ); if (skirmish->single == 0) return DR_NOLOCALMEMORY; skirmish->single->name = (char*)(skirmish->single + 1); strcpy( skirmish->single->name, name ); direct_util_recursive_pthread_mutex_init( &skirmish->single->lock ); pthread_cond_init( &skirmish->single->cond, NULL ); /* Keep back pointer to shared world data. */ skirmish->multi.shared = world->shared; return DR_OK; }
CoreFont * dfb_font_create( CoreDFB *core ) { CoreFont *font; font = (CoreFont *) D_CALLOC( 1, sizeof(CoreFont) ); font->core = core; direct_util_recursive_pthread_mutex_init( &font->lock ); /* the proposed pixel_format, may be changed by the font provider */ font->pixel_format = dfb_config->font_format ? : DSPF_A8; /* the state used to blit the glyphs, may be changed by the font provider */ dfb_state_init( &font->state ); font->state.blittingflags = DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_COLORIZE; font->glyph_infos = direct_tree_new(); D_MAGIC_SET( font, CoreFont ); return font; }
static void init_fallback_log( void ) { fallback_log.type = DLT_STDERR; fallback_log.fd = fileno( stderr ); direct_util_recursive_pthread_mutex_init( &fallback_log.lock ); D_MAGIC_SET( &fallback_log, DirectLog ); }
DirectResult fusion_ref_init (FusionRef *ref, const char *name, const FusionWorld *world) { D_ASSERT( ref != NULL ); D_ASSERT( name != NULL ); direct_util_recursive_pthread_mutex_init (&ref->single.lock); pthread_cond_init (&ref->single.cond, NULL); ref->single.refs = 0; ref->single.destroyed = false; ref->single.locked = 0; return DR_OK; }
DirectResult direct_log_create( DirectLogType type, const char *param, DirectLog **ret_log ) { DirectResult ret = DR_INVARG; DirectLog *log; log = D_CALLOC( 1, sizeof(DirectLog) ); if (!log) return D_OOM(); log->type = type; switch (type) { case DLT_STDERR: ret = init_stderr( log ); break; case DLT_FILE: ret = init_file( log, param ); break; case DLT_UDP: ret = init_udp( log, param ); break; } if (ret) D_FREE( log ); else { direct_util_recursive_pthread_mutex_init( &log->lock ); D_MAGIC_SET( log, DirectLog ); *ret_log = log; } return ret; }
int dfb_state_init( CardState *state, CoreDFB *core ) { D_ASSERT( state != NULL ); memset( state, 0, sizeof(CardState) ); state->core = core; state->fusion_id = fusion_id( dfb_core_world(core) ); state->modified = SMF_ALL; state->src_blend = DSBF_SRCALPHA; state->dst_blend = DSBF_INVSRCALPHA; state->render_options = dfb_config->render_options; state->matrix[0] = 0x10000; state->matrix[1] = 0x00000; state->matrix[2] = 0x00000; state->matrix[3] = 0x00000; state->matrix[4] = 0x10000; state->matrix[5] = 0x00000; state->matrix[6] = 0x00000; state->matrix[7] = 0x00000; state->matrix[8] = 0x10000; state->affine_matrix = DFB_TRUE; state->from = CSBR_FRONT; state->to = CSBR_BACK; direct_util_recursive_pthread_mutex_init( &state->lock ); direct_serial_init( &state->dst_serial ); direct_serial_init( &state->src_serial ); direct_serial_init( &state->src_mask_serial ); direct_serial_init( &state->src2_serial ); D_MAGIC_SET( state, CardState ); return 0; }
static DFBResult vt_init_switching() { const char cursoroff_str[] = "\033[?1;0;0c"; const char blankoff_str[] = "\033[9;0]"; char buf[32]; D_DEBUG_AT( VT, "%s()\n", __FUNCTION__ ); /* FIXME: Opening the device should be moved out of this function. */ snprintf(buf, 32, "/dev/tty%d", dfb_vt->num); dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY ); if (dfb_vt->fd < 0) { if (errno == ENOENT) { snprintf(buf, 32, "/dev/vc/%d", dfb_vt->num); dfb_vt->fd = open( buf, O_RDWR | O_NOCTTY ); if (dfb_vt->fd < 0) { if (errno == ENOENT) { D_PERROR( "DirectFB/core/vt: Couldn't open " "neither `/dev/tty%d' nor `/dev/vc/%d'!\n", dfb_vt->num, dfb_vt->num ); } else { D_PERROR( "DirectFB/core/vt: " "Error opening `%s'!\n", buf ); } return errno2result( errno ); } } else { D_PERROR( "DirectFB/core/vt: Error opening `%s'!\n", buf ); return errno2result( errno ); } } /* attach to the new TTY before doing anything like KDSETMODE with it, otherwise we'd get access denied error: */ ioctl( dfb_vt->fd, TIOCSCTTY, 0 ); write( dfb_vt->fd, cursoroff_str, sizeof(cursoroff_str) ); if (dfb_config->kd_graphics) { if (ioctl( dfb_vt->fd, KDSETMODE, KD_GRAPHICS ) < 0) { D_PERROR( "DirectFB/fbdev/vt: KD_GRAPHICS failed!\n" ); close( dfb_vt->fd ); return DFB_INIT; } } else { write( dfb_vt->fd, blankoff_str, sizeof(blankoff_str) ); } if (dfb_config->vt_switching) { struct vt_mode vt; struct sigaction sig_tty; memset( &sig_tty, 0, sizeof( sig_tty ) ); sig_tty.sa_handler = vt_switch_handler; sigfillset( &sig_tty.sa_mask ); if (sigaction( SIG_SWITCH_FROM, &sig_tty, &dfb_vt->sig_usr1 ) || sigaction( SIG_SWITCH_TO, &sig_tty, &dfb_vt->sig_usr2 )) { D_PERROR( "DirectFB/fbdev/vt: sigaction failed!\n" ); close( dfb_vt->fd ); return DFB_INIT; } vt.mode = VT_PROCESS; vt.waitv = 0; vt.relsig = SIG_SWITCH_FROM; vt.acqsig = SIG_SWITCH_TO; if (ioctl( dfb_vt->fd, VT_SETMODE, &vt ) < 0) { D_PERROR( "DirectFB/fbdev/vt: VT_SETMODE failed!\n" ); sigaction( SIG_SWITCH_FROM, &dfb_vt->sig_usr1, NULL ); sigaction( SIG_SWITCH_TO, &dfb_vt->sig_usr2, NULL ); close( dfb_vt->fd ); return DFB_INIT; } direct_util_recursive_pthread_mutex_init( &dfb_vt->lock ); pthread_cond_init( &dfb_vt->wait, NULL ); dfb_vt->vt_sig = -1; dfb_vt->thread = direct_thread_create( DTT_CRITICAL, vt_thread, NULL, "VT Switcher" ); } return DFB_OK; }
DirectThread * direct_thread_create( DirectThreadType thread_type, DirectThreadMainFunc thread_main, void *arg, const char *name ) { DirectThread *thread; pthread_attr_t attr; struct sched_param param; int policy; int priority; size_t stack_size; D_ASSERT( thread_main != NULL ); D_ASSERT( name != NULL ); D_DEBUG_AT( Direct_Thread, "%s( %s, %p(%p), '%s' )\n", __FUNCTION__, direct_thread_type_name(thread_type), thread_main, arg, name ); /* Create the key for the TSD (thread specific data). */ pthread_mutex_lock( &key_lock ); if (thread_key == -1) pthread_key_create( &thread_key, NULL ); pthread_mutex_unlock( &key_lock ); /* Allocate thread structure. */ thread = D_CALLOC( 1, sizeof(DirectThread) ); if (!thread) { D_OOM(); return NULL; } /* Write thread information to structure. */ thread->name = D_STRDUP( name ); thread->type = thread_type; thread->main = thread_main; thread->arg = arg; /* Initialize to -1 for synchronization. */ thread->thread = (pthread_t) -1; thread->tid = (pid_t) -1; /* Initialize mutex and condition. */ direct_util_recursive_pthread_mutex_init( &thread->lock ); pthread_cond_init( &thread->cond, NULL ); D_MAGIC_SET( thread, DirectThread ); /* Initialize scheduling and other parameters. */ pthread_attr_init( &attr ); pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ); /* Select scheduler. */ switch (direct_config->thread_scheduler) { case DCTS_FIFO: policy = SCHED_FIFO; break; case DCTS_RR: policy = SCHED_RR; break; default: policy = SCHED_OTHER; break; } if (pthread_attr_setschedpolicy( &attr, policy )) D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) ); /* Read (back) value. */ pthread_attr_getschedpolicy( &attr, &policy ); /* Select priority. */ switch (thread->type) { case DTT_CLEANUP: case DTT_INPUT: case DTT_OUTPUT: case DTT_MESSAGING: case DTT_CRITICAL: priority = thread->type * direct_config->thread_priority_scale / 100; break; default: priority = direct_config->thread_priority; break; } D_DEBUG_AT( Direct_ThreadInit, " -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority, sched_get_priority_min( policy ), sched_get_priority_max( policy ) ); if (priority < sched_get_priority_min( policy )) priority = sched_get_priority_min( policy ); if (priority > sched_get_priority_max( policy )) priority = sched_get_priority_max( policy ); param.sched_priority = priority; if (pthread_attr_setschedparam( &attr, ¶m )) D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority ); /* Select stack size? */ if (direct_config->thread_stack_size > 0) { if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size )) D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size ); } /* Read (back) value. */ pthread_attr_getstacksize( &attr, &stack_size ); /* Lock the thread mutex. */ D_DEBUG_AT( Direct_ThreadInit, " -> locking...\n" ); pthread_mutex_lock( &thread->lock ); /* Create and run the thread. */ D_DEBUG_AT( Direct_ThreadInit, " -> creating...\n" ); pthread_create( &thread->thread, &attr, direct_thread_main, thread ); pthread_attr_destroy( &attr ); pthread_getschedparam( thread->thread, &policy, ¶m ); D_INFO( "Direct/Thread: Started '%s' (%d) [%s %s/%s %d/%d] <%zu>...\n", name, thread->tid, direct_thread_type_name(thread_type), direct_thread_policy_name(policy), direct_thread_scheduler_name(direct_config->thread_scheduler), param.sched_priority, priority, stack_size ); #ifdef DIRECT_THREAD_WAIT_INIT /* Wait for completion of the thread's initialization. */ while (!thread->init) { D_DEBUG_AT( Direct_ThreadInit, " -> waiting...\n" ); pthread_cond_wait( &thread->cond, &thread->lock ); } D_DEBUG_AT( Direct_ThreadInit, " -> ...thread is running.\n" ); #endif /* Unlock the thread mutex. */ D_DEBUG_AT( Direct_ThreadInit, " -> unlocking...\n" ); pthread_mutex_unlock( &thread->lock ); D_DEBUG_AT( Direct_ThreadInit, " -> returning %p\n", thread ); return thread; }
DirectResult voodoo_manager_create( int fd, VoodooClient *client, VoodooServer *server, VoodooManager **ret_manager ) { DirectResult ret; VoodooManager *manager; int val; unsigned int len; static const int tos = IPTOS_LOWDELAY; D_ASSERT( fd >= 0 ); D_ASSERT( (client != NULL) ^ (server != NULL) ); D_ASSERT( ret_manager != NULL ); /* Allocate manager structure. */ manager = D_CALLOC( 1, sizeof(VoodooManager) ); if (!manager) { D_WARN( "out of memory" ); return DR_NOLOCALMEMORY; } D_DEBUG( "Voodoo/Manager: Creating manager at %p.\n", manager ); if (setsockopt( fd, SOL_IP, IP_TOS, &tos, sizeof(tos) ) < 0) D_PERROR( "Voodoo/Manager: Could not set IP_TOS!\n" ); if (setsockopt( fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one) ) < 0) D_PERROR( "Voodoo/Manager: Could not set TCP_NODELAY!\n" ); DUMP_SOCKET_OPTION( SO_SNDLOWAT ); DUMP_SOCKET_OPTION( SO_RCVLOWAT ); DUMP_SOCKET_OPTION( SO_SNDBUF ); DUMP_SOCKET_OPTION( SO_RCVBUF ); /* Create the hash table for dispatcher instances. */ ret = direct_hash_create( 251, &manager->instances.local ); if (ret) { D_FREE( manager ); return ret; } /* Create the hash table for requestor instances. */ ret = direct_hash_create( 251, &manager->instances.remote ); if (ret) { direct_hash_destroy( manager->instances.local ); D_FREE( manager ); return ret; } /* Store file descriptor. */ manager->fd = fd; /* Store client or server. */ manager->client = client; manager->server = server; /* Initialize all locks. */ direct_util_recursive_pthread_mutex_init( &manager->instances.lock ); direct_util_recursive_pthread_mutex_init( &manager->response.lock ); direct_util_recursive_pthread_mutex_init( &manager->input.lock ); direct_util_recursive_pthread_mutex_init( &manager->output.lock ); /* Initialize all wait conditions. */ pthread_cond_init( &manager->response.wait, NULL ); pthread_cond_init( &manager->input.wait, NULL ); pthread_cond_init( &manager->output.wait, NULL ); /* Set default buffer limit. */ manager->input.max = IN_BUF_MAX; D_MAGIC_SET( manager, VoodooManager ); /* Create all threads. */ manager->dispatcher = direct_thread_create( DTT_MESSAGING, manager_dispatch_loop, manager, "Voodoo Dispatch" ); manager->input.thread = direct_thread_create( DTT_INPUT, manager_input_loop, manager, "Voodoo Input" ); manager->output.thread = direct_thread_create( DTT_OUTPUT, manager_output_loop, manager, "Voodoo Output" ); /* Return the new manager. */ *ret_manager = manager; return DR_OK; }