Random Programming Tidbits

VxWorks example, setting up a write protected memory block

/* Must allocate on page boundry, so we use valloc quick n dirty */
/* Allocating in multiples of page boundry size, again quick n dirty */

char *vmPtr;

void barry_vm_alloc( void )
{
	vmPtr=valloc(4096);
	if( NULL == vmPtr )
		{
		printf("Cannot vm alloc\r\n");
		}
}

void barry_vm_set( int enable )
{
	vmBaseStateSet (NULL, vmPtr, 4096,
                    VM_STATE_MASK_WRITABLE,
                    (enable ? VM_STATE_WRITABLE_NOT : VM_STATE_WRITABLE));
}

void barry_vm_write( void )
{
	*vmPtr=123;
}

Fun with pthread

pthread_addr_t

Defined in bits/pthreadtypes.h

/* Attributes for threads.  */
typedef struct __pthread_attr_s
{
  int __detachstate;
  int __schedpolicy;
  struct __sched_param __schedparam;
  int __inheritsched;
  int __scope;
  size_t __guardsize;
  int __stackaddr_set;
  void *__stackaddr;
  size_t __stacksize;
} pthread_attr_t;
Calls to pthread_create() return error 12
Calling pthread_create() returned 12 as an unknown error meaning it didn't match the errors of the man page.

This happens if too many threads get created and are never joined. The fix is to detach the thread, as in the following example:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* print_foo( void *ptr )
{
        printf("Thread!\r\n");
        pthread_exit(NULL);
}

void create_thread(void)
{
        pthread_t thread1;
        pthread_attr_t attr;
        int ireg=pthread_create(&thread1,NULL,print_foo,(void*)NULL);
        printf("Create thread = %d\r\n",ireg);
        // Comment out the next line to see the '12' error occur.
        pthread_detach( thread1 );
}

int main( int argc, char *argv[] )
{
        while(1)
        {
       // Force many threads to start, to create the error condition
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        create_thread();
        sleep(1);
        }
}

BSD rt_entry structure for route and arp routes

## ROUTE.H ##
struct rtentry {
	struct	radix_node rt_nodes[2];	/* tree glue, and other values */
#define	rt_key(r)	((struct sockaddr *)((r)->rt_nodes->rn_key))
#define	rt_mask(r)	((struct sockaddr *)((r)->rt_nodes->rn_mask))
	struct	sockaddr *rt_gateway;	/* value */
	short	rt_flags;		/* up/down?, host/net */
	short	rt_refcnt;		/* # held references */
	u_long	rt_use;			/* raw # packets forwarded */
	struct	ifnet *rt_ifp;		/* the answer: interface to use */
	struct	ifaddr *rt_ifa;		/* the answer: interface to use */
	struct	sockaddr *rt_genmask;	/* for generation of cloned routes */
	caddr_t	rt_llinfo;		/* pointer to link level info cache */
	struct	rtentry *rt_gwroute;	/* implied entry for gatewayed routes */
                int	rt_mod;			/* last modified XXX */ 
	struct	rt_metrics rt_rmx;	/* metrics used by rx'ing protocols */
        struct  rtentry *rt_parent;     /* parent of route (if cloned) */
};

## if_ether.h ##
arptab and llinfo_arp
struct	arptab {
	struct	in_addr at_iaddr;	/* internet address */
	u_char	at_enaddr[6];		/* ethernet address */
	u_char	at_timer;		/* minutes since last reference */
	u_char	at_flags;		/* flags */
	struct	mbuf *at_hold;		/* last packet until resolved/timeout */
} ETHER_PACKED;

struct llinfo_arp {
	struct	llinfo_arp *la_next;
	struct	llinfo_arp *la_prev;
	struct	rtentry *la_rt;
	struct	mbuf *la_hold;		/* last packet until resolved/timeout */
	long	la_asked;		/* last time we QUERIED for this addr */
#define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */
} ETHER_PACKED;