int main(int argc, char **argv) {
    unsigned int i;
    unsigned int limit = 10;
    // Think of `list` as an array variable. In C, an array variable is
    // actually a pointer to the first element of the array.
    Item *list, *current_item;

    // Initialize the list
    current_item = list = allocate_item();

    //printf("\n  Got here. \n");
    init_list(list);

    // Create list items
    for(i = 0; i < limit; i ++) {
        // When creating a new item, set the new item's address to the struct
        // memeber `next_item` and then set `next_item` to `current_item` to advance
        // the list.
        Item *item = allocate_item();
        append_item(current_item, item);
        current_item->value = i;
        current_item = current_item->next_item;
    }

    // Reset the current item pointer to the start of the list so we can print the
    // list to stdout
    current_item = list;
    find_middle(list);
    printf("  Full list");
    print_list(list);

    list = reverse_list(list);
    //delete_item(list, 5);

    printf("\n\n  Full list");
    print_list(list);

    current_item = find_item(list, 4);

    printf("  Searched item: %d", current_item->value);
    // Leak memory.
}
Beispiel #2
0
int	add_member()
{
	struct	item * iptr;
	if (!( iptr = allocate_item()))
		return( failure( 27,"allocation","item") );
	else if (!( iptr->name = allocate_string( C.member )))
		return( failure( 27,"allocation","item->name") );
	else if (!( iptr->basic = allocate_string( C.basic )))
		return( failure( 27,"allocation","item->basic") );
	else 	
	{
		if (!( strcmp( C.basic, "struct" ) ))
			if (!( iptr->type = allocate_string( C.special )))
				return( failure( 27,"allocation","item->type") );
		iptr->dimension = C.dimension;
		iptr->indirection = C.isptr;
		C.isptr = 0;
		C.dimension=0;
		if (!( iptr->previous = C.last ))
			C.first = iptr;
		else	iptr->previous->next = iptr;
		C.last = iptr;
		if (!( strcmp( C.basic, "struct" ) )) 
		{
			if (!( strcmp(C.member, "first" ) ))
			{
				C.hasfirst=1;
				strcpy( C.premier, C.special );
			}
			else if (!( strcmp(C.member, "parent" ) ))
			{
				C.hasparent=1;
				strcpy( C.parent, C.special );
			}
			else if (!( strcmp(C.member, "previous" ) ))
			{
				C.hasprevious=1;
			}
			else if (!( strcmp(C.member, "next" ) ))
			{
				C.hasnext=1;
			}
		}
		return( 0 );
	}
}
Beispiel #3
0
/**
 * Manages the system.
 *
 * A system lifecycle consists of the three phases:
 * - startup
 * - running
 * - shutdown
 *
 * in the following order:
 * - startup internal memory (global system parametres, e.g. for input/output)
 * - startup knowledge memory (statics = state knowledge + logic knowledge)
 * - startup signal memory (knowledge models to be executed as operations)
 * - create startup signal and add to signal memory
 * - run signal checker loop (dynamics)
 * - destroy startup signal
 * - shutdown signal memory
 * - shutdown knowledge memory
 * - shutdown internal memory
 *
 * @param p0 the run source item
 */
void manage(void* p0) {

    log_terminated_message((void*) INFORMATION_LEVEL_LOG_MODEL, (void*) L"\n\n");
    log_terminated_message((void*) INFORMATION_LEVEL_LOG_MODEL, (void*) L"Manage system.");

    //
    // Variable declaration.
    //

    // The internal memory array.
    void* i = *NULL_POINTER_MEMORY_MODEL;
    // The knowledge memory part.
    void* k = *NULL_POINTER_MEMORY_MODEL;
    // The signal memory item.
    void* s = *NULL_POINTER_MEMORY_MODEL;

    //
    // The signal memory interrupt request flag.
    //
    // Unix system signal handlers that return normally must modify some global
    // variable in order to have any effect. Typically, the variable is one that
    // is examined periodically by the program during normal operation.
    //
    // Whether the data in an application concerns atoms, or mere text, one has to
    // be careful about the fact that access to a single datum is not necessarily
    // atomic. This means that it can take more than one instruction to read or
    // write a single object. In such cases, a signal handler might be invoked in
    // the middle of reading or writing the object.
    // The usage of data types that are always accessed atomically is one way to
    // cope with this problem. Therefore, this flag is of type sig_atomic_t.
    //
    // Reading and writing this data type is guaranteed to happen in a single
    // instruction, so there's no way for a handler to run in the middle of an access.
    // The type sig_atomic_t is always an integer data type, but which one it is,
    // and how many bits it contains, may vary from machine to machine.
    // In practice, one can assume that int and other integer types no longer than
    // int are atomic, that is objects of this type are always accessed atomically.
    // One can also assume that pointer types are atomic; that is very convenient.
    // Both of these assumptions are true on all of the machines that the GNU C
    // library supports and on all known POSIX systems.
    //
    // Why is the keyword "volatile" used here?
    //
    // In the following example, the code sets the value stored in "foo" to 0.
    // It then starts to poll that value repeatedly until it changes to 255:
    //
    // static int foo;
    // void bar(void) {
    //     foo = 0;
    //     while (foo != 255);
    // }
    //
    // An optimizing compiler will notice that no other code can possibly
    // change the value stored in "foo", and will assume that it will
    // remain equal to "0" at all times. The compiler will therefore
    // replace the function body with an infinite loop similar to this:
    //
    // void bar_optimized(void) {
    //     foo = 0;
    //     while (true);
    // }
    //
    // However, foo might represent a location that can be changed
    // by other elements of the computer system at any time,
    // such as a hardware register of a device connected to the CPU.
    // The above code would never detect such a change;
    // without the "volatile" keyword, the compiler assumes that
    // the current program is the only part of the system that could
    // change the value (which is by far the most common situation).
    //
    // To prevent the compiler from optimising code as above,
    // the "volatile" keyword is used:
    //
    // static volatile int foo;
    // void bar (void) {
    //     foo = 0;
    //     while (foo != 255);
    // }
    //
    // With this modification, the loop condition will not be optimised
    // away, and the system will detect the change when it occurs.
    //

    volatile sig_atomic_t* signal_memory_irq = (volatile sig_atomic_t*) *NULL_POINTER_MEMORY_MODEL;
    // The gnu/linux console interrupt request flag.
    volatile sig_atomic_t* gnu_linux_console_irq = (volatile sig_atomic_t*) *NULL_POINTER_MEMORY_MODEL;
    // The x window system interrupt request flag.
    volatile sig_atomic_t* x_window_system_irq = (volatile sig_atomic_t*) *NULL_POINTER_MEMORY_MODEL;
    // The www service interrupt request flag.
    volatile sig_atomic_t* www_service_irq = (volatile sig_atomic_t*) *NULL_POINTER_MEMORY_MODEL;
    // The cyboi service interrupt request flag.
    volatile sig_atomic_t* cyboi_service_irq = (volatile sig_atomic_t*) *NULL_POINTER_MEMORY_MODEL;

    // The signal memory mutex.
    pthread_mutex_t* signal_memory_mutex = (pthread_mutex_t*) *NULL_POINTER_MEMORY_MODEL;
    // The gnu/linux console mutex.
    pthread_mutex_t* gnu_linux_console_mutex = (pthread_mutex_t*) *NULL_POINTER_MEMORY_MODEL;
    // The x window system mutex.
    pthread_mutex_t* x_window_system_mutex = (pthread_mutex_t*) *NULL_POINTER_MEMORY_MODEL;
    // The www service mutex.
    pthread_mutex_t* www_service_mutex = (pthread_mutex_t*) *NULL_POINTER_MEMORY_MODEL;
    // The cyboi service mutex.
    pthread_mutex_t* cyboi_service_mutex = (pthread_mutex_t*) *NULL_POINTER_MEMORY_MODEL;

    // The signal memory sleep time.
    double* signal_memory_sleep_time = (double*) *NULL_POINTER_MEMORY_MODEL;
    // The gnu linux console sleep time.
    double* gnu_linux_console_sleep_time = (double*) *NULL_POINTER_MEMORY_MODEL;
    // The x window system sleep time.
    double* x_window_system_sleep_time = (double*) *NULL_POINTER_MEMORY_MODEL;
    // The www service sleep time.
    double* www_service_sleep_time = (double*) *NULL_POINTER_MEMORY_MODEL;
    // The cyboi service sleep time.
    double* cyboi_service_sleep_time = (double*) *NULL_POINTER_MEMORY_MODEL;

    //
    // Variable allocation.
    //

    // Allocate internal memory array.
    // CAUTION! The internal memory has a pre-defined count/size,
    // given by the constant INTERNAL_MEMORY_MEMORY_MODEL_COUNT.
    allocate_array((void*) &i, (void*) INTERNAL_MEMORY_MEMORY_MODEL_COUNT, (void*) POINTER_PRIMITIVE_MEMORY_ABSTRACTION);
    // Allocate knowledge memory part.
    allocate_part((void*) &k, (void*) NUMBER_0_INTEGER_MEMORY_MODEL, (void*) PART_PRIMITIVE_MEMORY_ABSTRACTION);
    // Allocate signal memory item.
    allocate_item((void*) &s, (void*) NUMBER_1000_INTEGER_MEMORY_MODEL, (void*) POINTER_PRIMITIVE_MEMORY_ABSTRACTION);

    // Allocate signal memory interrupt request flag.
    signal_memory_irq = (volatile sig_atomic_t*) malloc(*VOLATILE_ATOMIC_SIGNAL_TYPE_SIZE);
    // Allocate gnu/linux console interrupt request flag.
    gnu_linux_console_irq = (volatile sig_atomic_t*) malloc(*VOLATILE_ATOMIC_SIGNAL_TYPE_SIZE);
    // Allocate x window system interrupt request flag.
    x_window_system_irq = (volatile sig_atomic_t*) malloc(*VOLATILE_ATOMIC_SIGNAL_TYPE_SIZE);
    // Allocate www service interrupt request flag.
    www_service_irq = (volatile sig_atomic_t*) malloc(*VOLATILE_ATOMIC_SIGNAL_TYPE_SIZE);
    // Allocate cyboi service interrupt request flag.
    cyboi_service_irq = (volatile sig_atomic_t*) malloc(*VOLATILE_ATOMIC_SIGNAL_TYPE_SIZE);

    // Allocate signal memory mutex.
    signal_memory_mutex = (pthread_mutex_t*) malloc(*MUTEX_THREAD_TYPE_SIZE);
    // Allocate gnu/linux console mutex.
    gnu_linux_console_mutex = (pthread_mutex_t*) malloc(*MUTEX_THREAD_TYPE_SIZE);
    // Allocate x window system mutex.
    x_window_system_mutex = (pthread_mutex_t*) malloc(*MUTEX_THREAD_TYPE_SIZE);
    // Allocate www service mutex.
    www_service_mutex = (pthread_mutex_t*) malloc(*MUTEX_THREAD_TYPE_SIZE);
    // Allocate cyboi service mutex.
    cyboi_service_mutex = (pthread_mutex_t*) malloc(*MUTEX_THREAD_TYPE_SIZE);

    // Allocate signal memory sleep time.
    signal_memory_sleep_time = (double*) malloc(*DOUBLE_REAL_TYPE_SIZE);
    // Allocate gnu linux console sleep time.
    gnu_linux_console_sleep_time = (double*) malloc(*DOUBLE_REAL_TYPE_SIZE);
    // Allocate x window system sleep time.
    x_window_system_sleep_time = (double*) malloc(*DOUBLE_REAL_TYPE_SIZE);
    // Allocate www service sleep time.
    www_service_sleep_time = (double*) malloc(*DOUBLE_REAL_TYPE_SIZE);
    // Allocate cyboi service sleep time.
    cyboi_service_sleep_time = (double*) malloc(*DOUBLE_REAL_TYPE_SIZE);

    //
    // Variable initialisation.
    //

    // Initialise signal memory interrupt request flag.
    *signal_memory_irq = *NUMBER_0_INTEGER_MEMORY_MODEL;
    // Initialise gnu/linux console interrupt request flag.
    *gnu_linux_console_irq = *NUMBER_0_INTEGER_MEMORY_MODEL;
    // Initialise x window system interrupt request flag.
    *x_window_system_irq = *NUMBER_0_INTEGER_MEMORY_MODEL;
    // Initialise www service interrupt request flag.
    *www_service_irq = *NUMBER_0_INTEGER_MEMORY_MODEL;
    // Initialise cyboi service interrupt request flag.
    *cyboi_service_irq = *NUMBER_0_INTEGER_MEMORY_MODEL;

    //
    // In the following mutex initialisation functions, the second parameter
    // specifies attributes that are to be used to initialise the mutex.
    // If the parameter is null, the mutex is initialised with default attributes.
    //

    // Initialise signal memory mutex.
    pthread_mutex_init(signal_memory_mutex, *NULL_POINTER_MEMORY_MODEL);
    // Initialise gnu/linux console mutex.
    pthread_mutex_init(gnu_linux_console_mutex, *NULL_POINTER_MEMORY_MODEL);
    // Initialise x window system mutex.
    pthread_mutex_init(x_window_system_mutex, *NULL_POINTER_MEMORY_MODEL);
    // Initialise www service mutex.
    pthread_mutex_init(www_service_mutex, *NULL_POINTER_MEMORY_MODEL);
    // Initialise cyboi service mutex.
    pthread_mutex_init(cyboi_service_mutex, *NULL_POINTER_MEMORY_MODEL);

    // Initialise signal memory sleep time.
    *signal_memory_sleep_time = *NUMBER_0_1_DOUBLE_MEMORY_MODEL;
    // Initialise gnu linux console sleep time.
    *gnu_linux_console_sleep_time = *NUMBER_0_1_DOUBLE_MEMORY_MODEL;
    // Initialise x window system sleep time.
    *x_window_system_sleep_time = *NUMBER_0_1_DOUBLE_MEMORY_MODEL;
    // Initialise www service sleep time.
    *www_service_sleep_time = *NUMBER_0_1_DOUBLE_MEMORY_MODEL;
    // Initialise cyboi service sleep time.
    *cyboi_service_sleep_time = *NUMBER_0_1_DOUBLE_MEMORY_MODEL;

    //
    // System startup.
    //

    // Start up internal memory.
    //
    // CAUTION! The internal memory items have a fixed position,
    // determined by constants. The items HAVE TO be assigned an
    // initial value, since all source code relies on them.
    //
    // Most values are compared against the *NULL_POINTER_MEMORY_MODEL constant
    // to find out whether they are set or not. If now initial values
    // would be arbitrary pointers, the program would follow a wrong path,
    // because it would guess that an instance was properly allocated,
    // while in reality the value was just an arbitrary initial one.
    // Therefore, such values are initialised with the well-defined *NULL_POINTER_MEMORY_MODEL.
    //
    // CAUTION! ONLY ONE parameter can be handed over to threads!
    // For example, the tcp socket is running in an own thread.
    // Therefore, the knowledge memory and signal memory NEED TO BE ADDED
    // to the internal memory, in order to be forwardable to threads.

    startup_internal_memory(i, (void*) &k, (void*) &s,
        (void*) &signal_memory_irq, (void*) &signal_memory_mutex, (void*) &signal_memory_sleep_time,
        (void*) &gnu_linux_console_irq, (void*) &gnu_linux_console_mutex, (void*) &gnu_linux_console_sleep_time,
        (void*) &x_window_system_irq, (void*) &x_window_system_mutex, (void*) &x_window_system_sleep_time,
        (void*) &www_service_irq, (void*) &www_service_mutex, (void*) &www_service_sleep_time,
        (void*) &cyboi_service_irq, (void*) &cyboi_service_mutex, (void*) &cyboi_service_sleep_time);

    // Start up system signal handler.
    startup_system_signal_handler();

    //
    // System initialisation.
    //

    // Initialise system with an initial signal.
    initialise(s, p0, i);

    //
    // System shutdown.
    //

    // The following calls of "shutdown" procedures are just to be sure,
    // in case a cybol application developer has forgotten to call the
    // corresponding service shutdown operation in cybol logic templates.
    // The "interrupt" procedures are called within the "shutdown" procedures.

    // Shutdown gnu/linux console.
    maintain_shutting_gnu_linux_console(i, (void*) GNU_LINUX_CONSOLE_THREAD, (void*) GNU_LINUX_CONSOLE_EXIT);
    // Shutdown x window system.
    maintain_shutting_x_window_system(i, (void*) X_WINDOW_SYSTEM_THREAD, (void*) X_WINDOW_SYSTEM_EXIT);
    // Shutdown www service.
    maintain_shutting_socket(i, (void*) WWW_BASE_INTERNAL_MEMORY_MEMORY_NAME,(void*) WWW_SERVICE_THREAD, (void*) WWW_SERVICE_EXIT);
    // Shutdown cyboi service.
    maintain_shutting_socket(i, (void*) CYBOI_BASE_INTERNAL_MEMORY_MEMORY_NAME, (void*) CYBOI_SERVICE_THREAD, (void*) CYBOI_SERVICE_EXIT);

    //
    // Variable finalisation.
    //

    // CAUTION! Do NOT remove any internal memory internals!
    // The internals have a fixed position within the internal memory.
    // Removing them would shift all entries by one position and
    // thus make all entries invalid, since they could not be found
    // at their original index anymore.

    // Destroy signal memory mutex.
    pthread_mutex_destroy(signal_memory_mutex);
    // Destroy gnu/linux console mutex.
    pthread_mutex_destroy(gnu_linux_console_mutex);
    // Destroy x window system mutex.
    pthread_mutex_destroy(x_window_system_mutex);
    // Destroy www service mutex.
    pthread_mutex_destroy(www_service_mutex);
    // Destroy cyboi service mutex.
    pthread_mutex_destroy(cyboi_service_mutex);

    //
    // Variable deallocation.
    //

    // Deallocate signal memory interrupt request flag.
    free((void*) signal_memory_irq);
    // Deallocate gnu/linux console interrupt request flag.
    free((void*) gnu_linux_console_irq);
    // Deallocate x window system interrupt request flag.
    free((void*) x_window_system_irq);
    // Deallocate www service interrupt request flag.
    free((void*) www_service_irq);
    // Deallocate cyboi service interrupt request flag.
    free((void*) cyboi_service_irq);

    // Deallocate signal memory mutex.
    free((void*) signal_memory_mutex);
    // Deallocate gnu/linux console mutex.
    free((void*) gnu_linux_console_mutex);
    // Deallocate x window system mutex.
    free((void*) x_window_system_mutex);
    // Deallocate www service mutex.
    free((void*) www_service_mutex);
    // Deallocate cyboi service mutex.
    free((void*) cyboi_service_mutex);

    // Deallocate signal memory sleep time.
    free((void*) signal_memory_sleep_time);
    // Deallocate gnu linux console sleep time.
    free((void*) gnu_linux_console_sleep_time);
    // Deallocate x window system sleep time.
    free((void*) x_window_system_sleep_time);
    // Deallocate www service sleep time.
    free((void*) www_service_sleep_time);
    // Deallocate cyboi service sleep time.
    free((void*) cyboi_service_sleep_time);

    // Deallocate signal memory item.
    deallocate_item((void*) &s, (void*) NUMBER_1000_INTEGER_MEMORY_MODEL, (void*) POINTER_PRIMITIVE_MEMORY_ABSTRACTION);
    // Deallocate knowledge memory part.
    deallocate_part((void*) &k, (void*) NUMBER_0_INTEGER_MEMORY_MODEL, (void*) PART_PRIMITIVE_MEMORY_ABSTRACTION);
    // Deallocate internal memory array.
    deallocate_array((void*) &i, (void*) INTERNAL_MEMORY_MEMORY_MODEL_COUNT, (void*) POINTER_PRIMITIVE_MEMORY_ABSTRACTION);
}
Beispiel #4
0
static item_container*  allocate_container(item_types type, int cnt)
{
    item_container* result = allocate_item(item_container, type, cnt*sizeof(void*));
    result->count = cnt;
    return result;
}