|
From: <ljs...@us...> - 2006-09-14 02:04:18
|
Revision: 352
http://svn.sourceforge.net/cadcdev/?rev=352&view=rev
Author: ljsebald
Date: 2006-09-13 19:04:08 -0700 (Wed, 13 Sep 2006)
Log Message:
-----------
Adding in the first of the big network changes that I have been working on.
Modified Paths:
--------------
kos/kernel/libc/koslib/Makefile
Added Paths:
-----------
kos/include/arpa/
kos/include/arpa/inet.h
kos/include/netinet/
kos/include/netinet/in.h
kos/kernel/libc/koslib/inet_addr.c
Added: kos/include/arpa/inet.h
===================================================================
--- kos/include/arpa/inet.h (rev 0)
+++ kos/include/arpa/inet.h 2006-09-14 02:04:08 UTC (rev 352)
@@ -0,0 +1,26 @@
+/* KallistiOS ##version##
+
+ arpa/inet.h
+ Copyright (C)2006 Lawrence Sebald
+
+*/
+
+#ifndef __ARPA_INET_H
+#define __ARPA_INET_H
+
+#include <sys/cdefs.h>
+#include <netinet/in.h>
+
+__BEGIN_DECLS
+
+uint32 htonl(uint32 value);
+uint32 ntohl(uint32 value);
+
+uint16 htons(uint16 value);
+uint16 ntohs(uint16 value);
+
+in_addr_t inet_addr(const char *cp);
+
+__END_DECLS
+
+#endif /* __ARPA_INET_H */
Added: kos/include/netinet/in.h
===================================================================
--- kos/include/netinet/in.h (rev 0)
+++ kos/include/netinet/in.h 2006-09-14 02:04:08 UTC (rev 352)
@@ -0,0 +1,44 @@
+/* KallistiOS ##version##
+
+ netinet/in.h
+ Copyright (C)2006 Lawrence Sebald
+
+*/
+
+#ifndef __NETINET_IN_H
+#define __NETINET_IN_H
+
+#include <sys/cdefs.h>
+#include <arch/types.h>
+
+__BEGIN_DECLS
+
+typedef uint16 in_port_t;
+typedef uint32 in_addr_t;
+
+#ifndef __SA_FAMILY_T_DEFINED
+#define __SA_FAMILY_T_DEFINED
+typedef uint32 sa_family_t;
+#endif
+
+struct in_addr {
+ in_addr_t s_addr;
+};
+
+struct sockaddr_in {
+ sa_family_t sin_family;
+ in_port_t sin_port;
+ struct in_addr sin_addr;
+ unsigned char sin_zero[8];
+};
+
+#define INADDR_ANY 0x00000000
+#define INADDR_BROADCAST 0xFFFFFFFF
+
+/* IP Protocols */
+#define IPPROTO_IP 0
+#define IPPROTO_UDP 17
+
+__END_DECLS
+
+#endif /* __NETINET_IN_H */
Modified: kos/kernel/libc/koslib/Makefile
===================================================================
--- kos/kernel/libc/koslib/Makefile 2006-09-14 01:38:50 UTC (rev 351)
+++ kos/kernel/libc/koslib/Makefile 2006-09-14 02:04:08 UTC (rev 352)
@@ -10,6 +10,6 @@
OBJS = abort.o byteorder.o memset2.o memset4.o memcpy2.o memcpy4.o \
assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \
opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \
- telldir.o usleep.o
+ telldir.o usleep.o inet_addr.o
include $(KOS_BASE)/Makefile.prefab
Added: kos/kernel/libc/koslib/inet_addr.c
===================================================================
--- kos/kernel/libc/koslib/inet_addr.c (rev 0)
+++ kos/kernel/libc/koslib/inet_addr.c 2006-09-14 02:04:08 UTC (rev 352)
@@ -0,0 +1,49 @@
+/* KallistiOS ##version##
+
+ inet_addr.c
+ Copyright (C)2006 Lawrence Sebald
+
+*/
+
+#include <arpa/inet.h>
+#include <stdlib.h>
+
+in_addr_t inet_addr(const char *cp) {
+ in_addr_t result = 0;
+ long tmp;
+ char *ptr;
+
+ tmp = strtoul(cp, &ptr, 10);
+ if(tmp > 0xFF || cp == ptr) {
+ return (in_addr_t) -1;
+ }
+ else {
+ result = tmp << 24;
+ }
+
+ tmp = strtoul(ptr + 1, &ptr, 10);
+ if(tmp > 0xFF || cp == ptr) {
+ return (in_addr_t) -1;
+ }
+ else {
+ result |= tmp << 16;
+ }
+
+ tmp = strtoul(ptr + 1, &ptr, 10);
+ if(tmp > 0xFF || cp == ptr) {
+ return (in_addr_t) -1;
+ }
+ else {
+ result |= tmp << 8;
+ }
+
+ tmp = strtoul(ptr + 1, &ptr, 10);
+ if(tmp > 0xFF || cp == ptr) {
+ return (in_addr_t) -1;
+ }
+ else {
+ result |= tmp;
+ }
+
+ return (in_addr_t) htonl(result);
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2006-09-14 03:04:57
|
Revision: 354
http://svn.sourceforge.net/cadcdev/?rev=354&view=rev
Author: ljsebald
Date: 2006-09-13 20:04:48 -0700 (Wed, 13 Sep 2006)
Log Message:
-----------
Another networking change coming up. This is a bit of cleaning in the net_ipv4.c file.
Modified Paths:
--------------
kos/include/kos/net.h
kos/kernel/net/net_ipv4.c
Modified: kos/include/kos/net.h
===================================================================
--- kos/include/kos/net.h 2006-09-14 02:39:59 UTC (rev 353)
+++ kos/include/kos/net.h 2006-09-14 03:04:48 UTC (rev 354)
@@ -198,6 +198,10 @@
within the ip. */
uint32 net_ipv4_address(const uint8 addr[4]);
+/* Parse an IP address that is packet into a uint32 into an array of the
+ individual bytes */
+void net_ipv4_parse_address(uint32 addr, uint8 out[4]);
+
/***** net_udp.c **********************************************************/
/* Init */
Modified: kos/kernel/net/net_ipv4.c
===================================================================
--- kos/kernel/net/net_ipv4.c 2006-09-14 02:39:59 UTC (rev 353)
+++ kos/kernel/net/net_ipv4.c 2006-09-14 03:04:48 UTC (rev 354)
@@ -2,7 +2,7 @@
kernel/net/net_ipv4.c
- Copyright (C) 2005 Lawrence Sebald
+ Copyright (C) 2005, 2006 Lawrence Sebald
Portions adapted from KOS' old net_icmp.c file:
Copyright (c) 2002 Dan Potter
@@ -11,6 +11,8 @@
#include <stdio.h>
#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
#include <kos/net.h>
#include "net_ipv4.h"
#include "net_icmp.h"
@@ -22,7 +24,7 @@
uint32 net_ntohl(uint32 n) {
return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) |
- ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF);
+ ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF);
}
/* Perform an IP-style checksum on a block of data */
@@ -43,7 +45,8 @@
}
/* Determine if a given IP is in the current network */
-static int is_in_network(const uint8 src[4], const uint8 dest[4], const uint8 netmask[4]) {
+static int is_in_network(const uint8 src[4], const uint8 dest[4],
+ const uint8 netmask[4]) {
int i;
for(i = 0; i < 4; i++) {
@@ -55,19 +58,21 @@
}
/* Send a packet on the specified network adaptor */
-int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, int size) {
+int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data,
+ int size) {
uint8 dest_ip[4];
uint8 dest_mac[6];
uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)];
eth_hdr_t *ehdr;
- dest_ip[0] = (uint8)(hdr->dest & 0xFF);
- dest_ip[1] = (uint8)(hdr->dest >> 8);
- dest_ip[2] = (uint8)(hdr->dest >> 16);
- dest_ip[3] = (uint8)(hdr->dest >> 24);
+ if(net == NULL) {
+ net = net_default_dev;
+ }
- /* Is this the loopback address? */
- if(dest_ip[0] == 127 && dest_ip[1] == 0 && dest_ip[2] == 0 && dest_ip[3] == 1) {
+ net_ipv4_parse_address(ntohl(hdr->dest), dest_ip);
+
+ /* Is this the loopback address (127.0.0.1)? */
+ if(ntohl(hdr->dest) == 0x7F000001) {
/* Fill in the ethernet header */
ehdr = (eth_hdr_t *)pkt;
memset(ehdr->dest, 0, 6);
@@ -80,24 +85,29 @@
ehdr->type[1] = 0x00;
/* Put the IP header / data into our ethernet packet */
- memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f));
- memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data, size);
+ memcpy(pkt + sizeof(eth_hdr_t), hdr,
+ 4 * (hdr->version_ihl & 0x0f));
+ memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f),
+ data, size);
/* Send it away */
- net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) + size);
+ net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) +
+ size);
return 0;
}
- /* Is it in our network? */
- if(!is_in_network(net->ip_addr, dest_ip, net->netmask))
+ /* Is it in our network? */
+ if(!is_in_network(net->ip_addr, dest_ip, net->netmask)) {
memcpy(dest_ip, net->gateway, 4);
+ }
/* Get our destination's MAC address */
- if(net_arp_lookup(net, dest_ip, dest_mac) == -1)
+ if(net_arp_lookup(net, dest_ip, dest_mac) == -1) {
+ errno = ENETUNREACH;
return -1;
+ }
-
/* Fill in the ethernet header */
ehdr = (eth_hdr_t *)pkt;
memcpy(ehdr->dest, dest_mac, 6);
@@ -107,10 +117,12 @@
/* Put the IP header / data into our ethernet packet */
memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f));
- memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data, size);
+ memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data,
+ size);
/* Send it away */
- net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t), NETIF_BLOCK);
+ net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t),
+ NETIF_BLOCK);
return 0;
}
@@ -120,45 +132,58 @@
ip_hdr_t *ip;
int i;
uint8 *data;
+ uint16 *ethproto;
/* Get pointers */
- eth = (eth_hdr_t*)(pkt);
- ip = (ip_hdr_t*)(pkt + sizeof(eth_hdr_t));
- data = (uint8 *)(pkt + sizeof(eth_hdr_t) + 4*(ip->version_ihl & 0x0f));
+ eth = (eth_hdr_t*) (pkt);
+ ip = (ip_hdr_t*) (pkt + sizeof(eth_hdr_t));
+ data = (uint8 *) (pkt + sizeof(eth_hdr_t) + 4 *
+ (ip->version_ihl & 0x0f));
+ ethproto = (uint16 *) (pkt + 12);
- /* Non-IP */
- if (eth->type[0] != 0x08)
+ /* Make sure this packet is actually marked as an IP packet */
+ if(ntohs(*ethproto) != 0x0800) {
+ dbglog(DBG_KDEBUG, "net_ipv4: Discarding non IP packet\n");
return 0;
+ }
- if (eth->type[1] != 0x00)
- return 0;
-
/* Check ip header checksum */
i = ip->checksum;
ip->checksum = 0;
- ip->checksum = net_ipv4_checksum((uint16*)ip, 2 * (ip->version_ihl & 0x0f));
- if (i != ip->checksum) {
- dbglog(DBG_KDEBUG, "net_ipv4: ip with invalid checksum\n");
+ ip->checksum = net_ipv4_checksum((uint16*)ip, 2 *
+ (ip->version_ihl & 0x0f));
+
+ if(i != ip->checksum) {
+ dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP packet "
+ "with invalid checksum\n");
return 0;
}
- switch(ip->protocol) {
+ switch(ip->protocol) {
case 1:
- net_icmp_input(src, eth, ip, data, net_ntohs(ip->length) -
+ net_icmp_input(src, eth, ip, data, ntohs(ip->length) -
(ip->version_ihl & 0x0f) * 4);
break;
case 17:
- net_udp_input(src, eth, ip, data, net_ntohs(ip->length) -
+ net_udp_input(src, eth, ip, data, ntohs(ip->length) -
(ip->version_ihl & 0x0f) * 4);
break;
default:
- dbglog(DBG_KDEBUG, "net_ipv4: unknown ip protocol: %d\n", ip->protocol);
+ dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP "
+ "packet with unkown protocol: %d\n",
+ ip->protocol);
}
return 0;
}
uint32 net_ipv4_address(const uint8 addr[4]) {
- uint32 ad = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]);
- return ad;
+ return (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]);
}
+
+void net_ipv4_parse_address(uint32 addr, uint8 out[4]) {
+ out[0] = (uint8) ((addr >> 24) & 0xFF);
+ out[1] = (uint8) ((addr >> 16) & 0xFF);
+ out[2] = (uint8) ((addr >> 8) & 0xFF);
+ out[3] = (uint8) (addr & 0xFF);
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2006-09-16 16:18:36
|
Revision: 355
http://svn.sourceforge.net/cadcdev/?rev=355&view=rev
Author: ljsebald
Date: 2006-09-16 09:18:26 -0700 (Sat, 16 Sep 2006)
Log Message:
-----------
This is the last of the big networking changes for now. This update adds a completely new UDP system, and a working sockets system to go along with it.
Modified Paths:
--------------
kos/include/kos/net.h
kos/kernel/fs/Makefile
kos/kernel/net/net_core.c
kos/kernel/net/net_udp.c
kos/kernel/net/net_udp.h
Added Paths:
-----------
kos/include/kos/fs_socket.h
kos/include/sys/socket.h
kos/kernel/fs/fs_socket.c
Added: kos/include/kos/fs_socket.h
===================================================================
--- kos/include/kos/fs_socket.h (rev 0)
+++ kos/include/kos/fs_socket.h 2006-09-16 16:18:26 UTC (rev 355)
@@ -0,0 +1,38 @@
+/* KallistiOS ##version##
+
+ kos/fs_socket.h
+ Copyright (C) 2006 Lawrence Sebald
+
+*/
+
+#ifndef __KOS_FS_SOCKET_H
+#define __KOS_FS_SOCKET_H
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+
+#include <arch/types.h>
+#include <kos/limits.h>
+#include <kos/fs.h>
+#include <sys/queue.h>
+
+typedef struct net_socket {
+ /* List handle */
+ LIST_ENTRY(net_socket) sock_list;
+
+ /* Protocol of this socket. This corresponds to the IP protocol number */
+ int protocol;
+
+ /* Protocol specific data */
+ void *data;
+} net_socket_t;
+
+int fs_socket_init();
+int fs_socket_shutdown();
+
+int fs_socket_setflags(int sock, int flags);
+
+__END_DECLS
+
+#endif /* __KOS_FS_SOCKET_H */
+
Modified: kos/include/kos/net.h
===================================================================
--- kos/include/kos/net.h 2006-09-14 03:04:48 UTC (rev 354)
+++ kos/include/kos/net.h 2006-09-16 16:18:26 UTC (rev 355)
@@ -210,23 +210,6 @@
/* Shutdown */
void net_udp_shutdown();
-/* Send a raw UDP packet, without a socket */
-int net_udp_send_raw(netif_t *net, uint16 src_port, uint16 dst_port,
- const uint8 dst_ip[4], const uint8 *data, int size);
-
-/* Open a socket between the local system, and a remote host */
-int net_udp_sock_open(uint16 loc_port, uint32 loc_addr, uint16 rem_port,
- uint32 rem_addr);
-
-/* Close a previously opened socket */
-int net_udp_sock_close(int sock);
-
-/* Send a packet on a socket */
-int net_udp_send(int sock, const uint8 *data, int size);
-
-/* Recieve a packet on a socket */
-int net_udp_recv(int sock, uint8 *buf, int size);
-
/***** net_core.c *********************************************************/
/* Interface list; note: do not manipulate directly */
Added: kos/include/sys/socket.h
===================================================================
--- kos/include/sys/socket.h (rev 0)
+++ kos/include/sys/socket.h 2006-09-16 16:18:26 UTC (rev 355)
@@ -0,0 +1,56 @@
+/* KallistiOS ##version##
+
+ sys/socket.h
+ Copyright (C)2006 Lawrence Sebald
+
+*/
+
+#ifndef __SYS_SOCKET_H
+#define __SYS_SOCKET_H
+
+#include <sys/cdefs.h>
+#include <arch/types.h>
+
+__BEGIN_DECLS
+
+typedef uint32 socklen_t;
+
+#ifndef __SA_FAMILY_T_DEFINED
+#define __SA_FAMILY_T_DEFINED
+typedef uint32 sa_family_t;
+#endif
+
+struct sockaddr {
+ sa_family_t sa_family;
+ char sa_data[];
+};
+
+/* Socket types, currently only SOCK_DGRAM is available */
+#define SOCK_DGRAM 1
+
+/* Socket address families. Currently only AF_INET is available */
+#define AF_INET 1
+
+#define PF_INET AF_INET
+
+/* Socket shutdown macros. */
+#define SHUT_RD 0x00000001
+#define SHUT_WR 0x00000002
+#define SHUT_RDWR (SHUT_RD | SHUT_WR)
+
+int accept(int socket, struct sockaddr *address, socklen_t *address_len);
+int bind(int socket, const struct sockaddr *address, socklen_t address_len);
+int connect(int socket, const struct sockaddr *address, socklen_t address_len);
+int listen(int socket, int backlog);
+ssize_t recv(int socket, void *buffer, size_t length, int flags);
+ssize_t recvfrom(int socket, void *buffer, size_t length, int flags,
+ struct sockaddr *address, socklen_t *address_len);
+ssize_t send(int socket, const void *message, size_t length, int flags);
+ssize_t sendto(int socket, const void *message, size_t length, int flags,
+ const struct sockaddr *dest_addr, socklen_t dest_len);
+int shutdown(int socket, int how);
+int socket(int domain, int type, int protocol);
+
+__END_DECLS
+
+#endif /* __SYS_SOCKET_H */
Modified: kos/kernel/fs/Makefile
===================================================================
--- kos/kernel/fs/Makefile 2006-09-14 03:04:48 UTC (rev 354)
+++ kos/kernel/fs/Makefile 2006-09-16 16:18:26 UTC (rev 355)
@@ -6,7 +6,7 @@
# $Id: Makefile,v 1.3 2002/08/13 04:54:22 bardtx Exp $
OBJS = fs.o fs_romdisk.o fs_ramdisk.o fs_pty.o
-OBJS += fs_utils.o elf.o
+OBJS += fs_utils.o elf.o fs_socket.o
SUBDIRS =
include $(KOS_BASE)/Makefile.prefab
Added: kos/kernel/fs/fs_socket.c
===================================================================
--- kos/kernel/fs/fs_socket.c (rev 0)
+++ kos/kernel/fs/fs_socket.c 2006-09-16 16:18:26 UTC (rev 355)
@@ -0,0 +1,298 @@
+/* KallistiOS ##version##
+
+ fs_socket.c
+ Copyright (C) 2006 Lawrence Sebald
+
+*/
+
+#include <kos/mutex.h>
+#include <arch/spinlock.h>
+#include <kos/dbgio.h>
+#include <kos/fs.h>
+#include <kos/fs_socket.h>
+#include <kos/net.h>
+
+#include <errno.h>
+#include <string.h>
+#include <malloc.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "../net/net_ipv4.h"
+#include "../net/net_udp.h"
+
+/* Define the socket list type */
+LIST_HEAD(socket_list, net_socket);
+
+static struct socket_list sockets;
+static mutex_t *list_mutex;
+
+static void fs_socket_close(void *hnd) {
+ net_socket_t *sock = (net_socket_t *) hnd;
+
+ mutex_lock(list_mutex);
+ LIST_REMOVE(sock, sock_list);
+ mutex_unlock(list_mutex);
+
+ net_udp_close(hnd);
+
+ free(sock);
+}
+
+static off_t fs_socket_tell(void *hnd) {
+ errno = ESPIPE;
+ return (off_t) -1;
+}
+
+/* VFS handler */
+static vfs_handler_t vh = {
+ /* Name handler */
+ {
+ { 0 }, /* Name */
+ 0, /* tbfi */
+ 0x00010000, /* Version 1.0 */
+ 0, /* Flags */
+ NMMGR_TYPE_VFS,
+ NMMGR_LIST_INIT,
+ },
+
+ 0, NULL, /* No cache, privdata */
+
+ NULL, /* open */
+ fs_socket_close, /* close */
+ NULL, /* read */
+ NULL, /* write */
+ NULL, /* seek */
+ fs_socket_tell, /* tell */
+ NULL, /* total */
+ NULL, /* readdir */
+ NULL, /* ioctl */
+ NULL, /* rename */
+ NULL, /* unlink */
+ NULL, /* mmap */
+ NULL, /* complete */
+ NULL, /* stat */
+ NULL, /* mkdir */
+ NULL /* rmdir */
+};
+
+/* Have we been initialized? */
+static int initted = 0;
+
+int fs_socket_init() {
+ if(initted == 1)
+ return 0;
+
+ LIST_INIT(&sockets);
+
+ if(nmmgr_handler_add(&vh.nmmgr) < 0)
+ return -1;
+
+ list_mutex = mutex_create();
+ initted = 1;
+
+ return 0;
+}
+
+int fs_socket_shutdown() {
+ net_socket_t *c, *n;
+
+ if(initted == 0)
+ return 0;
+
+ mutex_lock(list_mutex);
+ c = LIST_FIRST(&sockets);
+ while(c != NULL) {
+ n = LIST_NEXT(c, sock_list);
+
+ vh.close(c);
+
+ free(c);
+ c = n;
+ }
+
+ if(nmmgr_handler_remove(&vh.nmmgr) < 0)
+ return -1;
+
+ mutex_destroy(list_mutex);
+
+ initted = 0;
+
+ return 0;
+}
+
+int fs_socket_setflags(int sock, int flags) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_setflags(hnd, flags);
+}
+
+int socket(int domain, int type, int protocol) {
+ net_socket_t *sock;
+ file_t hnd;
+
+ /* First, check the arguments for validity */
+ if(domain != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ if(type != SOCK_DGRAM) {
+ errno = EPROTONOSUPPORT;
+ return -1;
+ }
+
+ if(protocol != 0 && protocol != IPPROTO_UDP) {
+ errno = EPROTONOSUPPORT;
+ return -1;
+ }
+
+ /* Allocate the socket structure, if we have the space */
+ sock = (net_socket_t *) malloc(sizeof(net_socket_t));
+ if(!sock) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ /* Attempt to get a handle for this socket */
+ hnd = fs_open_handle(&vh, sock);
+ if(hnd < 0) {
+ free(sock);
+ return -1;
+ }
+
+ /* We only support UDP right now, so this is ok... */
+ sock->protocol = IPPROTO_UDP;
+
+ /* Initialize protocol-specific data */
+ if(net_udp_socket(sock, domain, type, protocol) == -1) {
+ fs_close(hnd);
+ return -1;
+ }
+
+ /* Add this socket into the list of sockets, and return */
+ mutex_lock(list_mutex);
+ LIST_INSERT_HEAD(&sockets, sock, sock_list);
+ mutex_unlock(list_mutex);
+
+ return hnd;
+}
+
+int accept(int sock, struct sockaddr *address, socklen_t *address_len) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_accept(hnd, address, address_len);
+}
+
+int bind(int sock, const struct sockaddr *address, socklen_t address_len) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_bind(hnd, address, address_len);
+}
+
+int connect(int sock, const struct sockaddr *address, socklen_t address_len) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_connect(hnd, address, address_len);
+}
+
+int listen(int sock, int backlog) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_listen(hnd, backlog);
+}
+
+ssize_t recv(int sock, void *buffer, size_t length, int flags) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_recv(hnd, buffer, length, flags);
+}
+
+ssize_t recvfrom(int sock, void *buffer, size_t length, int flags,
+ struct sockaddr *address, socklen_t *address_len) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_recvfrom(hnd, buffer, length, flags, address,
+ address_len);
+}
+
+ssize_t send(int sock, const void *message, size_t length, int flags) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_send(hnd, message, length, flags);
+}
+
+ssize_t sendto(int sock, const void *message, size_t length, int flags,
+ const struct sockaddr *dest_addr, socklen_t dest_len) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_sendto(hnd, message, length, flags, dest_addr, dest_len);
+}
+
+int shutdown(int sock, int how) {
+ net_socket_t *hnd;
+
+ hnd = (net_socket_t *) fs_get_handle(sock);
+ if(hnd == NULL) {
+ errno = EBADF;
+ return -1;
+ }
+
+ return net_udp_shutdownsock(hnd, how);
+}
Modified: kos/kernel/net/net_core.c
===================================================================
--- kos/kernel/net/net_core.c 2006-09-14 03:04:48 UTC (rev 354)
+++ kos/kernel/net/net_core.c 2006-09-16 16:18:26 UTC (rev 355)
@@ -10,6 +10,7 @@
#include <malloc.h>
#include <stdio.h>
#include <kos/net.h>
+#include <kos/fs_socket.h>
CVSID("$Id: net_core.c,v 1.5 2002/10/26 07:59:50 bardtx Exp $");
@@ -100,7 +101,7 @@
net_default_dev = n;
- return olddev;
+ return olddev;
}
/* Device detect / init */
@@ -144,6 +145,11 @@
/* Initialize the ARP cache */
net_arp_init();
+ /* Initialize the UDP system */
+ net_udp_init();
+
+ fs_socket_init();
+
return 0;
}
@@ -165,4 +171,9 @@
/* Shut down the ARP cache */
net_arp_shutdown();
+
+ /* Shut down the UDP system */
+ net_udp_shutdown();
+
+ fs_socket_shutdown();
}
Modified: kos/kernel/net/net_udp.c
===================================================================
--- kos/kernel/net/net_udp.c 2006-09-14 03:04:48 UTC (rev 354)
+++ kos/kernel/net/net_udp.c 2006-09-16 16:18:26 UTC (rev 355)
@@ -1,295 +1,689 @@
/* KallistiOS ##version##
kernel/net/net_udp.c
- Copyright (C) 2005 Lawrence Sebald
+ Copyright (C) 2005, 2006 Lawrence Sebald
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
+#include <arpa/inet.h>
#include <kos/net.h>
#include <kos/mutex.h>
+#include <kos/cond.h>
#include <sys/queue.h>
+#include <kos/dbgio.h>
+#include <kos/fs_socket.h>
+#include <sys/socket.h>
+#include <errno.h>
#include "net_ipv4.h"
#include "net_udp.h"
-typedef struct udp_pkt {
- TAILQ_ENTRY(udp_pkt) pkt_queue;
- udp_hdr_t hdr;
- uint8 *data;
- uint16 datasize;
-} udp_pkt_t;
+struct udp_pkt {
+ TAILQ_ENTRY(udp_pkt) pkt_queue;
+ struct sockaddr_in from;
+ uint8 *data;
+ uint16 datasize;
+};
TAILQ_HEAD(udp_pkt_queue, udp_pkt);
-typedef struct udp_sock {
- LIST_ENTRY(udp_sock) sock_list;
- int sock_num;
- uint16 loc_port;
- uint16 rem_port;
- uint32 loc_addr;
- uint32 rem_addr;
- struct udp_pkt_queue packets;
-} udp_sock_t;
+struct udp_sock {
+ LIST_ENTRY(udp_sock) sock_list;
+ struct sockaddr_in local_addr;
+ struct sockaddr_in remote_addr;
+ int flags;
+
+ struct udp_pkt_queue packets;
+};
+
LIST_HEAD(udp_sock_list, udp_sock);
-static struct udp_sock_list net_udp_socks = LIST_HEAD_INITIALIZER(0);
-static int cur_udp_sock = 0;
-static uint8 udp_buf[1514];
+static struct udp_sock_list net_udp_sockets = LIST_HEAD_INITIALIZER(0);
+static mutex_t *udp_mutex;
+static condvar_t *udp_packets_ready;
-int net_udp_sock_open(uint16 loc_port, uint32 loc_addr, uint16 rem_port, uint32 rem_addr) {
- udp_sock_t *ns;
+int net_udp_accept(net_socket_t *hnd, struct sockaddr *addr,
+ socklen_t *addr_len) {
+ errno = EOPNOTSUPP;
+ return -1;
+}
- LIST_FOREACH(ns, &net_udp_socks, sock_list) {
- if(ns->loc_port == loc_port && ns->loc_addr == loc_addr &&
- ns->rem_port == rem_port && ns->rem_addr == rem_addr) {
- dbglog(DBG_KDEBUG, "net_udp: Attempt to create already existing socket\n");
- return 0;
- }
- }
+int net_udp_bind(net_socket_t *hnd, const struct sockaddr *addr,
+ socklen_t addr_len) {
+ struct udp_sock *udpsock, *iter;
+ struct sockaddr_in *realaddr;
- ns = (udp_sock_t *)malloc(sizeof(udp_sock_t));
+ /* Verify the parameters sent in first */
+ if(addr == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
- ns->sock_num = ++cur_udp_sock;
- ns->loc_port = loc_port;
- ns->loc_addr = loc_addr;
- ns->rem_port = rem_port;
- ns->rem_addr = rem_addr;
+ if(addr->sa_family != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
- TAILQ_INIT(&ns->packets);
- LIST_INSERT_HEAD(&net_udp_socks, ns, sock_list);
+ /* Get the sockaddr_in structure, rather than the sockaddr one */
+ realaddr = (struct sockaddr_in *) addr;
- return cur_udp_sock;
+ mutex_lock(udp_mutex);
+
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
+
+ /* See if we requested a specific port or not */
+ if(realaddr->sin_port != 0) {
+ /* Make sure we don't already have a socket bound to the
+ port specified */
+
+ LIST_FOREACH(iter, &net_udp_sockets, sock_list) {
+ if(iter->local_addr.sin_port == realaddr->sin_port) {
+ mutex_unlock(udp_mutex);
+ errno = EADDRINUSE;
+ return -1;
+ }
+ }
+
+ udpsock->local_addr = *realaddr;
+ }
+ else {
+ uint16 port = 1024, tmp = 0;
+
+ /* Grab the first unused port >= 1024. This is, unfortunately, O(n^2) */
+ while(tmp != port) {
+ tmp = port;
+
+ LIST_FOREACH(iter, &net_udp_sockets, sock_list) {
+ if(iter->local_addr.sin_port == port) {
+ ++port;
+ break;
+ }
+ }
+ }
+
+ udpsock->local_addr = *realaddr;
+ udpsock->local_addr.sin_port = htons(port);
+ }
+
+ mutex_unlock(udp_mutex);
+
+ return 0;
}
-int net_udp_sock_close(int socknum) {
- udp_sock_t *ns;
- udp_pkt_t *pkt;
+int net_udp_connect(net_socket_t *hnd, const struct sockaddr *addr,
+ socklen_t addr_len) {
+ struct udp_sock *udpsock;
+ struct sockaddr_in *realaddr;
- LIST_FOREACH(ns, &net_udp_socks, sock_list) {
- if(ns->sock_num == socknum) {
- LIST_REMOVE(ns, sock_list);
- TAILQ_FOREACH(pkt, &ns->packets, pkt_queue) {
- TAILQ_REMOVE(&ns->packets, pkt, pkt_queue);
- free(pkt->data);
- free(pkt);
- }
- free(ns);
+ if(addr == NULL) {
+ errno = EFAULT;
+ return -1;
+ }
- return 0;
- }
- }
+ if(addr->sa_family != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
- dbglog(DBG_KDEBUG, "net_udp: Attempt to close unopened socket");
- return -1;
+ mutex_lock(udp_mutex);
+
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
+
+ if(udpsock->remote_addr.sin_addr.s_addr != INADDR_ANY) {
+ mutex_unlock(udp_mutex);
+ errno = EISCONN;
+ return -1;
+ }
+
+ realaddr = (struct sockaddr_in *) addr;
+ if(realaddr->sin_port == 0 || realaddr->sin_addr.s_addr == INADDR_ANY) {
+ mutex_unlock(udp_mutex);
+ errno = EADDRNOTAVAIL;
+ return -1;
+ }
+
+ udpsock->remote_addr.sin_addr.s_addr = realaddr->sin_addr.s_addr;
+ udpsock->remote_addr.sin_port = realaddr->sin_port;
+
+ mutex_unlock(udp_mutex);
+
+ return 0;
}
-int net_udp_recv(int sock, uint8 *buf, int size) {
- udp_sock_t *ns;
- udp_pkt_t *pkt;
+int net_udp_listen(net_socket_t *hnd, int backlog) {
+ errno = EOPNOTSUPP;
+ return -1;
+}
- LIST_FOREACH(ns, &net_udp_socks, sock_list) {
- if(ns->sock_num == sock) {
- pkt = TAILQ_FIRST(&ns->packets);
- if(pkt) {
- if(size >= pkt->datasize) {
- memcpy(buf, pkt->data, pkt->datasize);
- TAILQ_REMOVE(&ns->packets, pkt, pkt_queue);
- size = pkt->datasize;
- free(pkt->data);
- free(pkt);
- return size;
- }
- else {
- uint8 tbuf[pkt->datasize - size];
- memcpy(buf, pkt->data, size);
- memcpy(tbuf, pkt->data + size, pkt->datasize - size);
- free(pkt->data);
- pkt->data = (uint8 *)malloc(pkt->datasize - size);
- memcpy(pkt->data, tbuf, pkt->datasize - size);
- pkt->datasize -= size;
- return size;
- }
- }
- else {
- return 0;
- }
- }
- }
+ssize_t net_udp_recv(net_socket_t *hnd, void *buffer, size_t length, int flags) {
+ struct udp_sock *udpsock;
+ struct udp_pkt *pkt;
- dbglog(DBG_KDEBUG, "net_udp: attempt to recv on unopened socket\n");
+ mutex_lock(udp_mutex);
- return -1;
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
+
+ if(udpsock->remote_addr.sin_addr.s_addr == INADDR_ANY ||
+ udpsock->remote_addr.sin_port == 0) {
+ mutex_unlock(udp_mutex);
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ if(udpsock->flags & SHUT_RD) {
+ mutex_unlock(udp_mutex);
+ return 0;
+ }
+
+ if(buffer == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EFAULT;
+ return -1;
+ }
+
+ if(TAILQ_EMPTY(&udpsock->packets) && (udpsock->flags & O_NONBLOCK)) {
+ mutex_unlock(udp_mutex);
+ errno = EWOULDBLOCK;
+ return -1;
+ }
+
+ if(TAILQ_EMPTY(&udpsock->packets)) {
+ cond_wait(udp_packets_ready, udp_mutex);
+ }
+
+ pkt = TAILQ_FIRST(&udpsock->packets);
+
+ if(pkt->datasize > length) {
+ memcpy(buffer, pkt->data, length);
+ }
+ else {
+ memcpy(buffer, pkt->data, pkt->datasize);
+ length = pkt->datasize;
+ }
+
+ TAILQ_REMOVE(&udpsock->packets, pkt, pkt_queue);
+ free(pkt->data);
+ free(pkt);
+
+ mutex_unlock(udp_mutex);
+
+ return length;
}
-int net_udp_send(int sock, const uint8 *data, int size) {
- udp_sock_t *ns;
-
- LIST_FOREACH(ns, &net_udp_socks, sock_list) {
- if(ns->sock_num == sock) {
- ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)udp_buf;
- ip_hdr_t ip;
- int internsize;
+ssize_t net_udp_recvfrom(net_socket_t *hnd, void *buffer, size_t length,
+ int flags, struct sockaddr *addr,
+ socklen_t *addr_len) {
+ struct udp_sock *udpsock;
+ struct udp_pkt *pkt;
- /* Fill in the UDP Header */
- ps->src_addr = ns->loc_addr;
- ps->dst_addr = ns->rem_addr;
- ps->zero = 0;
- ps->proto = 17;
- ps->length = net_ntohs(size + sizeof(udp_hdr_t));
- ps->src_port = ns->loc_port;
- ps->dst_port = ns->rem_port;
- ps->hdrlength = ps->length;
- ps->checksum = 0;
- memcpy(ps->data, data, size);
+ mutex_lock(udp_mutex);
- if(size % 2) {
- internsize = size + 1;
- ps->data[internsize] = 0;
- }
- else
- internsize = size;
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
- /* Compute the UDP Checksum */
- ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (internsize + sizeof(udp_hdr_t) + 12) / 2);
+ if(udpsock->flags & SHUT_RD) {
+ mutex_unlock(udp_mutex);
+ return 0;
+ }
- /* Fill in the IP Header */
- ip.version_ihl = 0x45; /* 20 byte header, ipv4 */
- ip.tos = 0;
- ip.length = net_ntohs(sizeof(udp_hdr_t) + size + 20);
- ip.packet_id = 0;
- ip.flags_frag_offs = net_ntohs(0x4000);
- ip.ttl = 64;
- ip.protocol = 17; /* UDP */
- ip.checksum = 0;
- ip.src = ps->src_addr;
- ip.dest = ps->dst_addr;
+ if(buffer == NULL || addr_len == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EFAULT;
+ return -1;
+ }
- /* Compute the IP Checksum */
- ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2);
+ if(TAILQ_EMPTY(&udpsock->packets) && (udpsock->flags & O_NONBLOCK)) {
+ mutex_unlock(udp_mutex);
+ errno = EWOULDBLOCK;
+ return -1;
+ }
- net_ipv4_send_packet(net_default_dev, &ip, (uint8 *)(udp_buf + 12), sizeof(udp_hdr_t) + size);
+ while(TAILQ_EMPTY(&udpsock->packets)) {
+ cond_wait(udp_packets_ready, udp_mutex);
+ }
- return size;
- }
- }
+ pkt = TAILQ_FIRST(&udpsock->packets);
- dbglog(DBG_KDEBUG, "net_udp: attempt to send on unopened socket\n");
-
- return -1;
+ if(pkt->datasize > length) {
+ memcpy(buffer, pkt->data, length);
+ }
+ else {
+ memcpy(buffer, pkt->data, pkt->datasize);
+ length = pkt->datasize;
+ }
+
+ if(addr != NULL) {
+ struct sockaddr_in realaddr;
+
+ realaddr.sin_family = AF_INET;
+ realaddr.sin_addr.s_addr = pkt->from.sin_addr.s_addr;
+ realaddr.sin_port = pkt->from.sin_port;
+ memset(realaddr.sin_zero, 0, 8);
+
+ if(*addr_len < sizeof(struct sockaddr_in)) {
+ memcpy(addr, &realaddr, *addr_len);
+ }
+ else {
+ memcpy(addr, &realaddr, sizeof(struct sockaddr_in));
+ *addr_len = sizeof(struct sockaddr_in);
+ }
+ }
+
+ TAILQ_REMOVE(&udpsock->packets, pkt, pkt_queue);
+ free(pkt->data);
+ free(pkt);
+
+ mutex_unlock(udp_mutex);
+
+ return length;
}
-int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ip, const uint8 *data, int size) {
- ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t*)udp_buf;
- uint16 i;
- udp_sock_t *sock;
- udp_pkt_t *pkt;
+ssize_t net_udp_send(net_socket_t *hnd, const void *message, size_t length,
+ int flags) {
+ struct udp_sock *udpsock;
- ps->src_addr = ip->src;
- ps->dst_addr = ip->dest;
- ps->zero = 0;
- ps->proto = ip->protocol;
- memcpy(&ps->src_port, data, size);
- ps->length = net_ntohs(size);
+ mutex_lock(udp_mutex);
- if(size % 2) {
- ps->data[size - sizeof(udp_hdr_t)] = 0;
- ++size;
- }
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
- i = ps->checksum;
- ps->checksum = 0;
- ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (size + 12) / 2);
+ if(udpsock->flags & SHUT_WR) {
+ mutex_unlock(udp_mutex);
+ errno = EPIPE;
+ return -1;
+ }
-#ifdef DEBUG_UDP
- printf("UDP Header Dump:\n");
- printf(" Pseudo-Header:\n");
- printf("src_addr = 0x%08x\n", ps->src_addr);
- printf("dst_addr = 0x%08x\n", ps->dst_addr);
- printf("zero = 0x%02x\n", ps->zero);
- printf("proto = 0x%02x\n", ps->proto);
- printf("length = 0x%04x\n", ps->length);
- printf("src_port = 0x%04x\n", ps->src_port);
- printf("dst_port = 0x%04x\n", ps->dst_port);
- printf("hdrlength = 0x%04x\n", ps->hdrlength);
- printf("checksum = 0x%04x\n", ps->checksum);
-#endif
+ if(udpsock->remote_addr.sin_addr.s_addr == INADDR_ANY ||
+ udpsock->remote_addr.sin_port == 0) {
+ mutex_unlock(udp_mutex);
+ errno = ENOTCONN;
+ return -1;
+ }
- if(i != ps->checksum) {
- dbglog(DBG_KDEBUG, "net_udp: discarding UDP packet with invalid checksum\n");
- dbglog(DBG_KDEBUG, "net_udp: was %x, expected %x\n", i, ps->checksum);
- return -1;
- }
+ if(message == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EFAULT;
+ return -1;
+ }
- LIST_FOREACH(sock, &net_udp_socks, sock_list) {
- if(sock->loc_port == ps->dst_port && sock->loc_addr == ps->dst_addr &&
- ((sock->rem_port == ps->src_port && sock->rem_addr == ps->src_addr) ||
- (sock->rem_port == 0 && sock->rem_addr == 0))) {
- sock->rem_port = ps->src_port;
- sock->rem_addr = ps->src_addr;
- pkt = (udp_pkt_t *) malloc(sizeof(udp_pkt_t));
- pkt->datasize = size - sizeof(udp_hdr_t);
- pkt->data = (uint8 *) malloc(pkt->datasize);
- memcpy(&pkt->hdr, &ps->src_port, sizeof(udp_hdr_t));
- memcpy(pkt->data, ps->data, pkt->datasize);
- TAILQ_INSERT_TAIL(&sock->packets, pkt, pkt_queue);
- return 0;
- }
- }
+ if(udpsock->local_addr.sin_port == 0) {
+ uint16 port = 1024, tmp = 0;
+ struct udp_sock *iter;
- dbglog(DBG_KDEBUG, "net_udp: discarding UDP packet for unopened socket\n");
+ /* Grab the first unused port >= 1024. This is, unfortunately, O(n^2) */
+ while(tmp != port) {
+ tmp = port;
- return 0;
+ LIST_FOREACH(iter, &net_udp_sockets, sock_list) {
+ if(iter->local_addr.sin_port == port) {
+ ++port;
+ break;
+ }
+ }
+ }
+
+ udpsock->local_addr.sin_port = htons(port);
+ }
+
+ mutex_unlock(udp_mutex);
+
+ return net_udp_send_raw(NULL, udpsock->local_addr.sin_addr.s_addr,
+ udpsock->local_addr.sin_port,
+ udpsock->remote_addr.sin_addr.s_addr,
+ udpsock->remote_addr.sin_port, (uint8 *) message,
+ length);
}
-int net_udp_send_raw(netif_t *net, uint16 src_port, uint16 dst_port, const uint8 ipa[4],
- const uint8 *data, int size) {
- ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)udp_buf;
- ip_hdr_t ip;
- int internsize;
+ssize_t net_udp_sendto(net_socket_t *hnd, const void *message, size_t length,
+ int flags, const struct sockaddr *addr,
+ socklen_t addr_len) {
+ struct udp_sock *udpsock;
+ struct sockaddr_in *realaddr;
- /* Fill in the UDP Header */
- if(net == NULL) /* Sending from the loopback device? */
- ps->src_addr = 0x0100007f; /* 127.0.0.1 */
- else
- ps->src_addr = net_ntohl(net_ipv4_address(net->ip_addr));
- ps->dst_addr = net_ntohl(net_ipv4_address(ipa));
- ps->zero = 0;
- ps->proto = 17;
- ps->length = net_ntohs(size + sizeof(udp_hdr_t));
- ps->src_port = net_ntohs(src_port);
- ps->dst_port = net_ntohs(dst_port);
- ps->hdrlength = ps->length;
- ps->checksum = 0;
- memcpy(ps->data, data, size);
+ mutex_lock(udp_mutex);
- if(size % 2) {
- internsize = size + 1;
- ps->data[internsize] = 0;
- }
- else
- internsize = size;
-
+ udpsock = (struct udp_sock *)hnd->data;
+ if(udpsock == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EBADF;
+ return -1;
+ }
- /* Compute the UDP Checksum */
- ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (internsize + sizeof(udp_hdr_t) + 12) / 2);
+ if(udpsock->flags & SHUT_WR) {
+ mutex_unlock(udp_mutex);
+ errno = EPIPE;
+ return -1;
+ }
- /* Fill in the IP Header */
- ip.version_ihl = 0x45; /* 20 byte header, ipv4 */
- ip.tos = 0;
- ip.length = net_ntohs(sizeof(udp_hdr_t) + size + 20);
- ip.packet_id = 0;
- ip.flags_frag_offs = net_ntohs(0x4000);
- ip.ttl = 64;
- ip.protocol = 17; /* UDP */
- ip.checksum = 0;
- ip.src = ps->src_addr;
- ip.dest = ps->dst_addr;
+ if(message == NULL || addr == NULL) {
+ mutex_unlock(udp_mutex);
+ errno = EFAULT;
+ return -1;
+ }
- /* Compute the IP Checksum */
- ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2);
+ realaddr = (struct sockaddr_in *) addr;
- return net_ipv4_send_packet(net, &ip, (uint8 *)(udp_buf + 12), sizeof(udp_hdr_t) + size);
+ if(udpsock->local_ad...
[truncated message content] |
|
From: <ba...@us...> - 2006-09-17 23:44:15
|
Revision: 358
http://svn.sourceforge.net/cadcdev/?rev=358&view=rev
Author: bardtx
Date: 2006-09-17 16:44:08 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
kos: Patch #1552702 from SourceForge:
A patch that includes realpath() to gain support for "." and ".." in
pathnames. Also includes some small changes to map standard functions to KOS
functions.
Modified Paths:
--------------
kos/include/kos/limits.h
kos/kernel/libc/koslib/Makefile
Added Paths:
-----------
kos/include/limits.h
kos/kernel/libc/koslib/chdir.c
kos/kernel/libc/koslib/creat.c
kos/kernel/libc/koslib/getcwd.c
kos/kernel/libc/koslib/mkdir.c
kos/kernel/libc/koslib/realpath.c
kos/kernel/libc/koslib/rename.c
kos/kernel/libc/koslib/rmdir.c
kos/kernel/libc/koslib/sleep.c
Modified: kos/include/kos/limits.h
===================================================================
--- kos/include/kos/limits.h 2006-09-17 23:33:39 UTC (rev 357)
+++ kos/include/kos/limits.h 2006-09-17 23:44:08 UTC (rev 358)
@@ -11,5 +11,6 @@
#define __KOS_LIMITS_H
#define MAX_FN_LEN 256 /* Max filename length */
+#define PATH_MAX 4095 /* Max path length */
#endif /* __KOS_LIMITS_H */
Added: kos/include/limits.h
===================================================================
--- kos/include/limits.h (rev 0)
+++ kos/include/limits.h 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,13 @@
+/* KallistiOS ##version##
+
+ limits.h
+ Copyright (C)2006 Dan Potter
+
+*/
+
+#ifndef __LIMITS_H
+#define __LIMITS_H
+
+#include <kos/limits.h>
+
+#endif /* __LIMITS_H */
Modified: kos/kernel/libc/koslib/Makefile
===================================================================
--- kos/kernel/libc/koslib/Makefile 2006-09-17 23:33:39 UTC (rev 357)
+++ kos/kernel/libc/koslib/Makefile 2006-09-17 23:44:08 UTC (rev 358)
@@ -10,6 +10,7 @@
OBJS = abort.o byteorder.o memset2.o memset4.o memcpy2.o memcpy4.o \
assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \
opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \
- telldir.o usleep.o inet_addr.o
+ telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \
+ creat.o sleep.o rmdir.o rename.o
include $(KOS_BASE)/Makefile.prefab
Added: kos/kernel/libc/koslib/chdir.c
===================================================================
--- kos/kernel/libc/koslib/chdir.c (rev 0)
+++ kos/kernel/libc/koslib/chdir.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,12 @@
+/* KallistiOS ##version##
+
+ chdir.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <kos/fs.h>
+
+int chdir(const char *path)
+{
+ return fs_chdir(path);
+}
Added: kos/kernel/libc/koslib/creat.c
===================================================================
--- kos/kernel/libc/koslib/creat.c (rev 0)
+++ kos/kernel/libc/koslib/creat.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,12 @@
+/* KallistiOS ##version##
+
+ creat.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <fcntl.h>
+
+int creat(const char *pathname, mode_t mode)
+{
+ return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode);
+}
Added: kos/kernel/libc/koslib/getcwd.c
===================================================================
--- kos/kernel/libc/koslib/getcwd.c (rev 0)
+++ kos/kernel/libc/koslib/getcwd.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,23 @@
+/* KallistiOS ##version##
+
+ getcwd.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <string.h>
+#include <errno.h>
+
+#include <kos/fs.h>
+
+char *getcwd(char *buf, size_t size)
+{
+ const char *wd = fs_getwd();
+
+ if (strlen(wd) + 1 > size) {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ strcpy(buf, wd);
+ return buf;
+}
Added: kos/kernel/libc/koslib/mkdir.c
===================================================================
--- kos/kernel/libc/koslib/mkdir.c (rev 0)
+++ kos/kernel/libc/koslib/mkdir.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,12 @@
+/* KallistiOS ##version##
+
+ mkdir.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <kos/fs.h>
+
+int mkdir(const char *pathname, mode_t mode)
+{
+ return fs_mkdir(pathname);
+}
Added: kos/kernel/libc/koslib/realpath.c
===================================================================
--- kos/kernel/libc/koslib/realpath.c (rev 0)
+++ kos/kernel/libc/koslib/realpath.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003 Constantin S. Svintsoff <ko...@ic...>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+/*
+ * char *realpath(const char *path, char resolved[PATH_MAX]);
+ *
+ * Find the real name of path, by removing all ".", ".." and symlink
+ * components. Returns (resolved) on success, or (NULL) on failure,
+ * in which case the path which caused trouble is left in (resolved).
+ */
+char *
+realpath(const char *path, char resolved[PATH_MAX])
+{
+ char *p, *q, *s;
+ size_t left_len, resolved_len;
+ int serrno;
+ char left[PATH_MAX], next_token[PATH_MAX];
+
+ serrno = errno;
+ if (path[0] == '/') {
+ resolved[0] = '/';
+ resolved[1] = '\0';
+ if (path[1] == '\0')
+ return (resolved);
+ resolved_len = 1;
+ left_len = strlcpy(left, path + 1, sizeof(left));
+ } else {
+ if (getcwd(resolved, PATH_MAX) == NULL) {
+ strlcpy(resolved, ".", PATH_MAX);
+ return (NULL);
+ }
+ resolved_len = strlen(resolved);
+ left_len = strlcpy(left, path, sizeof(left));
+ }
+ if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+
+ /*
+ * Iterate over path components in `left'.
+ */
+ while (left_len != 0) {
+ /*
+ * Extract the next path component and adjust `left'
+ * and its length.
+ */
+ p = strchr(left, '/');
+ s = p ? p : left + left_len;
+ if (s - left >= sizeof(next_token)) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ memcpy(next_token, left, s - left);
+ next_token[s - left] = '\0';
+ left_len -= s - left;
+ if (p != NULL)
+ memmove(left, s + 1, left_len + 1);
+ if (resolved[resolved_len - 1] != '/') {
+ if (resolved_len + 1 >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ resolved[resolved_len++] = '/';
+ resolved[resolved_len] = '\0';
+ }
+ if (next_token[0] == '\0')
+ continue;
+ else if (strcmp(next_token, ".") == 0)
+ continue;
+ else if (strcmp(next_token, "..") == 0) {
+ /*
+ * Strip the last path component except when we have
+ * single "/"
+ */
+ if (resolved_len > 1) {
+ resolved[resolved_len - 1] = '\0';
+ q = strrchr(resolved, '/') + 1;
+ *q = '\0';
+ resolved_len = q - resolved;
+ }
+ continue;
+ }
+
+ /*
+ * Append the next path component and lstat() it. If
+ * lstat() fails we still can return successfully if
+ * there are no more path components left.
+ */
+ resolved_len = strlcat(resolved, next_token, PATH_MAX);
+ if (resolved_len >= PATH_MAX) {
+ errno = ENAMETOOLONG;
+ return (NULL);
+ }
+ }
+
+ /*
+ * Remove trailing slash except when the resolved pathname
+ * is a single "/".
+ */
+ if (resolved_len > 1 && resolved[resolved_len - 1] == '/')
+ resolved[resolved_len - 1] = '\0';
+ return (resolved);
+}
Added: kos/kernel/libc/koslib/rename.c
===================================================================
--- kos/kernel/libc/koslib/rename.c (rev 0)
+++ kos/kernel/libc/koslib/rename.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,12 @@
+/* KallistiOS ##version##
+
+ rename.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <kos/fs.h>
+
+int rename(const char *oldpath, const char *newpath)
+{
+ return fs_rename(oldpath, newpath);
+}
Added: kos/kernel/libc/koslib/rmdir.c
===================================================================
--- kos/kernel/libc/koslib/rmdir.c (rev 0)
+++ kos/kernel/libc/koslib/rmdir.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,12 @@
+/* KallistiOS ##version##
+
+ rmdir.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <kos/fs.h>
+
+int rmdir(const char *pathname)
+{
+ return fs_rmdir(pathname);
+}
Added: kos/kernel/libc/koslib/sleep.c
===================================================================
--- kos/kernel/libc/koslib/sleep.c (rev 0)
+++ kos/kernel/libc/koslib/sleep.c 2006-09-17 23:44:08 UTC (rev 358)
@@ -0,0 +1,14 @@
+/* KallistiOS ##version##
+
+ sleep.c
+ Copyright (C)2005 Walter van Niftrik
+*/
+
+#include <kos/thread.h>
+
+unsigned int sleep(unsigned int seconds)
+{
+ thd_sleep(seconds * 1000);
+
+ return 0;
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ba...@us...> - 2006-09-18 00:45:27
|
Revision: 373
http://svn.sourceforge.net/cadcdev/?rev=373&view=rev
Author: bardtx
Date: 2006-09-17 17:45:21 -0700 (Sun, 17 Sep 2006)
Log Message:
-----------
kos: Revert limits.h change earlier.. breaks other stuff
Modified Paths:
--------------
kos/kernel/libc/koslib/realpath.c
Removed Paths:
-------------
kos/include/limits.h
Deleted: kos/include/limits.h
===================================================================
--- kos/include/limits.h 2006-09-18 00:31:09 UTC (rev 372)
+++ kos/include/limits.h 2006-09-18 00:45:21 UTC (rev 373)
@@ -1,13 +0,0 @@
-/* KallistiOS ##version##
-
- limits.h
- Copyright (C)2006 Dan Potter
-
-*/
-
-#ifndef __LIMITS_H
-#define __LIMITS_H
-
-#include <kos/limits.h>
-
-#endif /* __LIMITS_H */
Modified: kos/kernel/libc/koslib/realpath.c
===================================================================
--- kos/kernel/libc/koslib/realpath.c 2006-09-18 00:31:09 UTC (rev 372)
+++ kos/kernel/libc/koslib/realpath.c 2006-09-18 00:45:21 UTC (rev 373)
@@ -30,6 +30,7 @@
#include <sys/param.h>
#include <sys/stat.h>
+#include <kos/limits.h>
#include <errno.h>
#include <stdlib.h>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2007-08-03 04:19:58
|
Revision: 430
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=430&view=rev
Author: ljsebald
Date: 2007-08-02 21:19:54 -0700 (Thu, 02 Aug 2007)
Log Message:
-----------
Adding in a few more inet functions for dealing with parsing and packing internet addresses.
Modified Paths:
--------------
kos/include/arpa/inet.h
kos/include/netinet/in.h
kos/kernel/libc/koslib/Makefile
kos/kernel/libc/koslib/inet_addr.c
Added Paths:
-----------
kos/kernel/libc/koslib/inet_aton.c
kos/kernel/libc/koslib/inet_ntoa.c
kos/kernel/libc/koslib/inet_ntop.c
kos/kernel/libc/koslib/inet_pton.c
Modified: kos/include/arpa/inet.h
===================================================================
--- kos/include/arpa/inet.h 2007-07-29 03:21:16 UTC (rev 429)
+++ kos/include/arpa/inet.h 2007-08-03 04:19:54 UTC (rev 430)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
arpa/inet.h
- Copyright (C)2006 Lawrence Sebald
+ Copyright (C) 2006, 2007 Lawrence Sebald
*/
@@ -9,10 +9,13 @@
#define __ARPA_INET_H
#include <sys/cdefs.h>
-#include <netinet/in.h>
__BEGIN_DECLS
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
uint32 htonl(uint32 value);
uint32 ntohl(uint32 value);
@@ -20,7 +23,14 @@
uint16 ntohs(uint16 value);
in_addr_t inet_addr(const char *cp);
+int inet_aton(const char *cp, struct in_addr *pin);
+int inet_pton(int af, const char *src, void *dst);
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
+
+/* Non-reentrant */
+char *inet_ntoa(struct in_addr addr);
+
__END_DECLS
#endif /* __ARPA_INET_H */
Modified: kos/include/netinet/in.h
===================================================================
--- kos/include/netinet/in.h 2007-07-29 03:21:16 UTC (rev 429)
+++ kos/include/netinet/in.h 2007-08-03 04:19:54 UTC (rev 430)
@@ -1,7 +1,7 @@
/* KallistiOS ##version##
netinet/in.h
- Copyright (C)2006 Lawrence Sebald
+ Copyright (C) 2006, 2007 Lawrence Sebald
*/
@@ -13,8 +13,15 @@
__BEGIN_DECLS
+#ifndef __IN_PORT_T_DEFINED
+#define __IN_PORT_T_DEFINED
typedef uint16 in_port_t;
+#endif
+
+#ifndef __IN_ADDR_T_DEFINED
+#define __IN_ADDR_T_DEFINED
typedef uint32 in_addr_t;
+#endif
#ifndef __SA_FAMILY_T_DEFINED
#define __SA_FAMILY_T_DEFINED
@@ -34,10 +41,13 @@
#define INADDR_ANY 0x00000000
#define INADDR_BROADCAST 0xFFFFFFFF
+#define INADDR_NONE 0xFFFFFFFF
/* IP Protocols */
-#define IPPROTO_IP 0
-#define IPPROTO_UDP 17
+#define IPPROTO_IP 0
+#define IPPROTO_ICMP 1
+#define IPPROTO_TCP 6
+#define IPPROTO_UDP 17
__END_DECLS
Modified: kos/kernel/libc/koslib/Makefile
===================================================================
--- kos/kernel/libc/koslib/Makefile 2007-07-29 03:21:16 UTC (rev 429)
+++ kos/kernel/libc/koslib/Makefile 2007-08-03 04:19:54 UTC (rev 430)
@@ -11,6 +11,7 @@
assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \
opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \
telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \
- creat.o sleep.o rmdir.o rename.o
+ creat.o sleep.o rmdir.o rename.o inet_pton.o inet_ntop.o \
+ inet_ntoa.o inet_aton.o
include $(KOS_BASE)/Makefile.prefab
Modified: kos/kernel/libc/koslib/inet_addr.c
===================================================================
--- kos/kernel/libc/koslib/inet_addr.c 2007-07-29 03:21:16 UTC (rev 429)
+++ kos/kernel/libc/koslib/inet_addr.c 2007-08-03 04:19:54 UTC (rev 430)
@@ -1,49 +1,19 @@
/* KallistiOS ##version##
inet_addr.c
- Copyright (C)2006 Lawrence Sebald
+ Copyright (C) 2006, 2007 Lawrence Sebald
*/
#include <arpa/inet.h>
-#include <stdlib.h>
in_addr_t inet_addr(const char *cp) {
- in_addr_t result = 0;
- long tmp;
- char *ptr;
+ struct in_addr addr;
- tmp = strtoul(cp, &ptr, 10);
- if(tmp > 0xFF || cp == ptr) {
- return (in_addr_t) -1;
+ /* inet_aton() returns 0 on failure, 1 on success */
+ if(inet_aton(cp, &addr)) {
+ return addr.s_addr;
}
- else {
- result = tmp << 24;
- }
- tmp = strtoul(ptr + 1, &ptr, 10);
- if(tmp > 0xFF || cp == ptr) {
- return (in_addr_t) -1;
- }
- else {
- result |= tmp << 16;
- }
-
- tmp = strtoul(ptr + 1, &ptr, 10);
- if(tmp > 0xFF || cp == ptr) {
- return (in_addr_t) -1;
- }
- else {
- result |= tmp << 8;
- }
-
- tmp = strtoul(ptr + 1, &ptr, 10);
- if(tmp > 0xFF || cp == ptr) {
- return (in_addr_t) -1;
- }
- else {
- result |= tmp;
- }
-
- return (in_addr_t) htonl(result);
+ return INADDR_NONE;
}
Added: kos/kernel/libc/koslib/inet_aton.c
===================================================================
--- kos/kernel/libc/koslib/inet_aton.c (rev 0)
+++ kos/kernel/libc/koslib/inet_aton.c 2007-08-03 04:19:54 UTC (rev 430)
@@ -0,0 +1,118 @@
+/* KallistiOS ##version##
+
+ inet_aton.c
+ Copyright (C) 2007 Lawrence Sebald
+
+*/
+
+#include <arpa/inet.h>
+
+int inet_aton(const char *cp, struct in_addr *pin) {
+ int parts[4] = { 0 };
+ int count = 0;
+ int base = 0;
+ char tmp;
+
+ for(; *cp && count < 4; ++cp) {
+ if(*cp == '.') {
+ ++count;
+ base = 0;
+ }
+ else if(base == 0) {
+ /* Determine which base this part is in */
+ if(*cp == '0') {
+ tmp = *++cp;
+
+ if(tmp == '.') {
+ base = 0;
+ parts[count++] = 0;
+ }
+ else if(tmp == '\0') {
+ base = 0;
+ parts[count] = 0;
+ --cp;
+ }
+ else if(tmp != 'x' && tmp != 'X') {
+ /* Octal, handle the character just read too. */
+ base = 8;
+ parts[count] = *cp - '0';
+ }
+ else {
+ /* Hexadecimal */
+ base = 16;
+ }
+ }
+ else if(*cp > '0' && *cp <= '9') {
+ /* Decimal, handle the digit */
+ base = 10;
+ parts[count] = *cp - '0';
+ }
+ else {
+ /* Non-number starting character... bail out. */
+ return 0;
+ }
+ }
+ else if(base == 10 && *cp >= '0' && *cp <= '9') {
+ parts[count] *= 10;
+ parts[count] += *cp - '0';
+ }
+ else if(base == 8 && *cp >= '0' && *cp <= '7') {
+ parts[count] <<= 3;
+ parts[count] += *cp - '0';
+ }
+ else if(base == 16) {
+ parts[count] <<= 4;
+
+ if(*cp >= '0' && *cp <= '9') {
+ parts[count] += *cp - '0';
+ }
+ else if(*cp >= 'A' && *cp <= 'F') {
+ parts[count] += *cp - 'A' + 10;
+ }
+ else if(*cp >= 'a' && *cp <= 'f') {
+ parts[count] += *cp - 'a' + 10;
+ }
+ else {
+ /* Invalid hex digit */
+ return 0;
+ }
+ }
+ else {
+ /* Invalid digit, and not a dot... bail */
+ return 0;
+ }
+ }
+
+ if(count == 4) {
+ /* Too many dots, bail out */
+ return 0;
+ }
+
+ /* Validate each part */
+ if(count == 0) {
+ /* Easiest case, store our computed part, and it's done */
+ pin->s_addr = htonl(parts[0]);
+ }
+ else if(count == 1) {
+ if(parts[0] > 0xFF || parts[1] > 0xFFFFFF)
+ return 0;
+
+ pin->s_addr = htonl(parts[0] << 24 | parts[1]);
+ }
+ else if(count == 2) {
+ if(parts[0] > 0xFF || parts[1] > 0xFF || parts[2] > 0xFFFF)
+ return 0;
+
+ pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | parts[2]);
+ }
+ else {
+ if(parts[0] > 0xFF || parts[1] > 0xFF ||
+ parts[2] > 0xFF || parts[3] > 0xFF)
+ return 0;
+
+ pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 |
+ parts[2] << 8 | parts[3]);
+ }
+
+ return 1;
+}
Added: kos/kernel/libc/koslib/inet_ntoa.c
===================================================================
--- kos/kernel/libc/koslib/inet_ntoa.c (rev 0)
+++ kos/kernel/libc/koslib/inet_ntoa.c 2007-08-03 04:19:54 UTC (rev 430)
@@ -0,0 +1,45 @@
+/* KallistiOS ##version##
+
+ inet_ntoa.c
+ Copyright (C) 2007 Lawrence Sebald
+
+*/
+
+#include <arpa/inet.h>
+
+char *inet_ntoa(struct in_addr addr) {
+ static char str[16]; /* XXX.XXX.XXX.XXX = 15 chars + 1 for NUL */
+ char tmp[3];
+ int i, part;
+ char *ch = tmp;
+ char *ch2 = str;
+
+ /* Parse each 8 bits individually. */
+ for(i = 0; i < 4; ++i) {
+ /* Treat the 32-bit address value as if it were an array of 8-bit
+ values. This works, regardless of the endianness of the host system
+ because the specs require the address passed in here to be in
+ network byte order (big endian). */
+ part = ((uint8 *) &addr.s_addr)[i];
+
+ do {
+ *ch++ = '0' + (char)(part % 10);
+ part /= 10;
+ } while(part);
+
+ /* tmp now contains the inverse of the number that is in the given
+ 8 bits. Reverse it for the final result, rewinding ch to the
+ beginning of tmp in the process. */
+ while(ch != tmp) {
+ *ch2++ = *--ch;
+ }
+
+ *ch2++ = '.';
+ }
+
+ /* There's a trailing '.' at the end of the address, change it to the
+ required NUL character */
+ *--ch2 = 0;
+
+ return str;
+}
Added: kos/kernel/libc/koslib/inet_ntop.c
===================================================================
--- kos/kernel/libc/koslib/inet_ntop.c (rev 0)
+++ kos/kernel/libc/koslib/inet_ntop.c 2007-08-03 04:19:54 UTC (rev 430)
@@ -0,0 +1,58 @@
+/* KallistiOS ##version##
+
+ inet_ntop.c
+ Copyright (C) 2007 Lawrence Sebald
+
+*/
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) {
+ char tmp[3];
+ int i, part;
+ char *ch = tmp;
+ char *ch2 = dst;
+ struct in_addr *addr = (struct in_addr *)src;
+
+ if(af != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ /* Parse each 8 bits individually. */
+ for(i = 0; i < 4; ++i) {
+ /* Treat the 32-bit address value as if it were an array of 8-bit
+ values. This works, regardless of the endianness of the host system
+ because the specs require the address passed in here to be in
+ network byte order (big endian). */
+ part = ((uint8 *) &addr->s_addr)[i];
+
+ do {
+ *ch++ = '0' + (char)(part % 10);
+ part /= 10;
+ } while(part);
+
+ /* tmp now contains the inverse of the number that is in the given
+ 8 bits. Reverse it for the final result, rewinding ch to the
+ beginning of tmp in the process. */
+ while(ch != tmp && size) {
+ *ch2++ = *--ch;
+ --size;
+ }
+
+ if(!size) {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ *ch2++ = '.';
+ --size;
+ }
+
+ /* There's a trailing '.' at the end of the address, change it to the
+ required NUL character */
+ *--ch2 = 0;
+
+ return dst;
+}
Added: kos/kernel/libc/koslib/inet_pton.c
===================================================================
--- kos/kernel/libc/koslib/inet_pton.c (rev 0)
+++ kos/kernel/libc/koslib/inet_pton.c 2007-08-03 04:19:54 UTC (rev 430)
@@ -0,0 +1,51 @@
+/* KallistiOS ##version##
+
+ inet_pton.c
+ Copyright (C) 2007 Lawrence Sebald
+
+*/
+
+#include <arpa/inet.h>
+#include <errno.h>
+
+int inet_pton(int af, const char *src, void *dst) {
+ int parts[4] = { 0 };
+ int count = 0;
+ struct in_addr *addr = (struct in_addr *)dst;
+
+ if(af != AF_INET) {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+
+ for(; *src && count < 4; ++src) {
+ if(*src == '.') {
+ ++count;
+ }
+ /* Unlike inet_aton(), inet_pton() only supports decimal parts */
+ else if(*src >= '0' && *src <= '9') {
+ parts[count] *= 10;
+ parts[count] += *src - '0';
+ }
+ else {
+ /* Invalid digit, and not a dot... bail */
+ return 0;
+ }
+ }
+
+ if(count != 3) {
+ /* Not the right number of parts, bail */
+ return 0;
+ }
+
+ /* Validate each part, note that unlike inet_aton(), inet_pton() only
+ supports the standard xxx.xxx.xxx.xxx addresses. */
+ if(parts[0] > 0xFF || parts[1] > 0xFF ||
+ parts[2] > 0xFF || parts[3] > 0xFF)
+ return 0;
+
+ addr->s_addr = htonl(parts[0] << 24 | parts[1] << 16 |
+ parts[2] << 8 | parts[3]);
+
+ return 1;
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2007-12-12 01:12:29
|
Revision: 551
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=551&view=rev
Author: ljsebald
Date: 2007-12-11 17:12:25 -0800 (Tue, 11 Dec 2007)
Log Message:
-----------
Committing C-style comments patch from quzar.
Modified Paths:
--------------
kos/include/kos/dbgio.h
kos/kernel/arch/dreamcast/hardware/flashrom.c
kos/kernel/arch/dreamcast/hardware/scif.c
kos/kernel/arch/dreamcast/hardware/video.c
kos/kernel/arch/dreamcast/include/dc/flashrom.h
kos/kernel/arch/dreamcast/include/dc/fmath.h
Modified: kos/include/kos/dbgio.h
===================================================================
--- kos/include/kos/dbgio.h 2007-11-24 05:20:47 UTC (rev 550)
+++ kos/include/kos/dbgio.h 2007-12-12 01:12:25 UTC (rev 551)
@@ -15,110 +15,110 @@
#include <arch/types.h>
-/// This struct represents a single dbgio interface. This should represent
-/// a generic pollable console interface. We will store an ordered list of
-/// these statically linked into the program and fall back from one to the
-/// next until one returns true for detected(). Note that the last device in
-/// this chain is the null console, which will always return true.
+/* This struct represents a single dbgio interface. This should represent
+ a generic pollable console interface. We will store an ordered list of
+ these statically linked into the program and fall back from one to the
+ next until one returns true for detected(). Note that the last device in
+ this chain is the null console, which will always return true. */
typedef struct dbgio_handler {
- /// Name of the dbgio handler
+ /* Name of the dbgio handler */
const char * name;
- /// Returns 1 if the device is available and usable, or 0 if it
- /// appears not to be.
+ /* Returns 1 if the device is available and usable, or 0 if it
+ appears not to be. */
int (*detected)();
- /// Init the interface with default parameters.
+ /* Init the interface with default parameters. */
int (*init)();
- /// Shut down the interface
+ /* Shut down the interface */
int (*shutdown)();
- /// Set polled/IRQ usage
+ /* Set polled/IRQ usage */
int (*set_irq_usage)(int mode);
- /// Read one char from the console or -1 if there's nothing to read,
- /// or an error condition exists (check errno).
+ /* Read one char from the console or -1 if there's nothing to read,
+ or an error condition exists (check errno). */
int (*read)();
- /// Write one char to the console (may need to call flush()).
- /// Returns the number of chars written or -1 on error.
+ /* Write one char to the console (may need to call flush()).
+ Returns the number of chars written or -1 on error. */
int (*write)(int c);
- /// Flush any queued written bytes. Returns -1 on error.
+ /* Flush any queued written bytes. Returns -1 on error. */
int (*flush)();
- /// Send an entire buffer. Returns the number of chars written or
- /// -1 on error. If xlat is non-zero, then newline transformations
- /// may occur.
+ /* Send an entire buffer. Returns the number of chars written or
+ -1 on error. If xlat is non-zero, then newline transformations
+ may occur. */
int (*write_buffer)(const uint8 *data, int len, int xlat);
- /// Read a buffer (block). Returns the number of chars read or
- /// -1 on error.
+ /* Read a buffer (block). Returns the number of chars read or
+ -1 on error. */
int (*read_buffer)(uint8 *data, int len);
} dbgio_handler_t;
-// These two should be initialized in arch.
+/* These two should be initialized in arch. */
extern dbgio_handler_t * dbgio_handlers[];
extern int dbgio_handler_cnt;
-// This is defined by the shared code, in case there's no valid handler.
+/* This is defined by the shared code, in case there's no valid handler. */
extern dbgio_handler_t dbgio_null;
-/// Manually select a new dbgio interface by name. Returns 0 on success or
-/// -1 on error. Note that even if the given device isn't detected, this
-/// will still let you select it.
+/* Manually select a new dbgio interface by name. Returns 0 on success or
+ -1 on error. Note that even if the given device isn't detected, this
+ will still let you select it. */
int dbgio_dev_select(const char * name);
-/// Returns the name of the currently selected device.
+/* Returns the name of the currently selected device. */
const char * dbgio_dev_get();
-/// Initialize the dbgio console. The device selection process is as
-/// described above.
+/* Initialize the dbgio console. The device selection process is as
+ described above. */
int dbgio_init();
-/// Set IRQ usage - we default to polled
+/* Set IRQ usage - we default to polled */
int dbgio_set_irq_usage(int mode);
#define DBGIO_MODE_POLLED 0
#define DBGIO_MODE_IRQ 1
-/// Read one char from the console or -1 if there's nothing to read,
-/// or an error condition exists (check errno).
+/* Read one char from the console or -1 if there's nothing to read,
+ or an error condition exists (check errno). */
int dbgio_read();
-/// Write one char to the console (may need to call flush()).
-/// Returns the number of chars written or -1 on error.
+/* Write one char to the console (may need to call flush()).
+ Returns the number of chars written or -1 on error. */
int dbgio_write(int c);
-/// Flush any queued written bytes. Returns -1 on error.
+/* Flush any queued written bytes. Returns -1 on error. */
int dbgio_flush();
-/// Send an entire buffer. Returns the number of chars written or
-/// -1 on error.
+/* Send an entire buffer. Returns the number of chars written or
+ -1 on error. */
int dbgio_write_buffer(const uint8 *data, int len);
-/// Read a buffer (block). Returns the number of chars read or
-/// -1 on error.
+/* Read a buffer (block). Returns the number of chars read or
+ -1 on error. */
int dbgio_read_buffer(uint8 *data, int len);
-/// Send an entire buffer. Returns the number of chars written or
-/// -1 on error. Newline translations may occur.
+/* Send an entire buffer. Returns the number of chars written or
+ -1 on error. Newline translations may occur. */
int dbgio_write_buffer_xlat(const uint8 *data, int len);
-/// Send a string (null-terminated). Returns the number of chars
-/// written or -1 on error.
+/* Send a string (null-terminated). Returns the number of chars
+ written or -1 on error. */
int dbgio_write_str(const char *str);
-/// Disable debug I/O globally
+/* Disable debug I/O globally */
void dbgio_disable();
-/// Enable debug I/O globally
+/* Enable debug I/O globally */
void dbgio_enable();
-/// Printf functionality
+/* Printf functionality */
int dbgio_printf(const char *fmt, ...) __printflike(1, 2);
__END_DECLS
-#endif // __KOS_DBGIO_H
+#endif /* __KOS_DBGIO_H */
Modified: kos/kernel/arch/dreamcast/hardware/flashrom.c
===================================================================
--- kos/kernel/arch/dreamcast/hardware/flashrom.c 2007-11-24 05:20:47 UTC (rev 550)
+++ kos/kernel/arch/dreamcast/hardware/flashrom.c 2007-12-12 01:12:25 UTC (rev 551)
@@ -158,7 +158,7 @@
that's easiest to deal with. Block 0 is the magic block, so we
won't check that. */
for (i=0; i<bmcnt*8; i++) {
- // Little shortcut
+ /* Little shortcut */
if (bitmap[i / 8] == 0)
i += 8;
@@ -273,58 +273,58 @@
typedef struct {
union {
struct {
- // Block 0xE0
- uint16 blockid; // Should be 0xE0
- uint8 prodname[4]; // SEGA
- uint8 unk1; // 0x13
- uint8 method;
- uint8 unk2[2]; // 0x00 0x00
- uint8 ip[4]; // These are all in big-endian notation
+ /* Block 0xE0 */
+ uint16 blockid; /* Should be 0xE0 */
+ uint8 prodname[4]; /* SEGA */
+ uint8 unk1; /* 0x13 */
+ uint8 method;
+ uint8 unk2[2]; /* 0x00 0x00 */
+ uint8 ip[4]; /* These are all in big-endian notation */
uint8 nm[4];
uint8 bc[4];
uint8 dns1[4];
uint8 dns2[4];
uint8 gw[4];
- uint8 unk3[4]; // All zeros
- char hostname[24]; // Host name
+ uint8 unk3[4]; /* All zeros */
+ char hostname[24]; /* Host name */
uint16 crc;
} e0;
struct {
- // Block E2
- uint16 blockid; // Should be 0xE2
+ /* Block E2 */
+ uint16 blockid; /* Should be 0xE2 */
uint8 unk[12];
char email[48];
uint16 crc;
} e2;
struct {
- // Block E4
- uint16 blockid; // Should be 0xE4
+ /* Block E4 */
+ uint16 blockid; /* Should be 0xE4 */
uint8 unk[32];
char smtp[28];
uint16 crc;
} e4;
struct {
- // Block E5
- uint16 blockid; // Should be 0xE5
+ /* Block E5 */
+ uint16 blockid; /* Should be 0xE5 */
uint8 unk[36];
char pop3[24];
uint16 crc;
} e5;
struct {
- // Block E6
- uint16 blockid; // Should be 0xE6
+ /* Block E6 */
+ uint16 blockid; /* Should be 0xE6 */
uint8 unk[40];
char pop3_login[20];
uint16 crc;
} e6;
struct {
- // Block E7
- uint16 blockid; // Should be 0xE7
+ /* Block E7 */
+ uint16 blockid; /* Should be 0xE7 */
uint8 unk[12];
char pop3_passwd[32];
char proxy_host[16];
@@ -332,8 +332,8 @@
} e7;
struct {
- // Block E8
- uint16 blockid; // Should be 0xE8
+ /* Block E8 */
+ uint16 blockid; /* Should be 0xE8 */
uint8 unk1[48];
uint16 proxy_port;
uint16 unk2;
@@ -342,8 +342,8 @@
} e8;
struct {
- // Block E9
- uint16 blockid; // Should be 0xE9
+ /* Block E9 */
+ uint16 blockid; /* Should be 0xE9 */
uint8 unk[40];
char ppp_passwd[20];
uint16 crc;
@@ -356,12 +356,12 @@
isp_settings_t * isp = (isp_settings_t *)buffer;
int found = 0;
- // Clean out the output config buffer.
+ /* Clean out the output config buffer. */
memset(out, 0, sizeof(flashrom_ispcfg_t));
- // Get the E0 config block
+ /* Get the E0 config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_IP_SETTINGS, buffer) >= 0) {
- // Fill in values from it
+ /* Fill in values from it */
out->method = isp->e0.method;
memcpy(out->ip, isp->e0.ip, 4);
memcpy(out->nm, isp->e0.nm, 4);
@@ -375,45 +375,45 @@
found++;
}
- // Get the email config block
+ /* Get the email config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_EMAIL, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->email, isp->e2.email, 48);
out->email_valid = 1;
found++;
}
- // Get the smtp config block
+ /* Get the smtp config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_SMTP, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->smtp, isp->e4.smtp, 28);
out->smtp_valid = 1;
found++;
}
- // Get the pop3 config block
+ /* Get the pop3 config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->pop3, isp->e5.pop3, 24);
out->pop3_valid = 1;
found++;
}
- // Get the pop3 login config block
+ /* Get the pop3 login config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3LOGIN, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->pop3_login, isp->e6.pop3_login, 20);
out->pop3_login_valid = 1;
found++;
}
- // Get the pop3 passwd config block
+ /* Get the pop3 passwd config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3PASSWD, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->pop3_passwd, isp->e7.pop3_passwd, 32);
memcpy(out->proxy_host, isp->e7.proxy_host, 16);
@@ -421,9 +421,9 @@
found++;
}
- // Get the PPP login config block
+ /* Get the PPP login config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_PPPLOGIN, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
out->proxy_port = isp->e8.proxy_port;
memcpy(out->ppp_login, isp->e8.ppp_login, 8);
@@ -431,9 +431,9 @@
found++;
}
- // Get the PPP passwd config block
+ /* Get the PPP passwd config block */
if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_PPPPASSWD, buffer) >= 0) {
- // Fill in the values from it
+ /* Fill in the values from it */
memcpy(out->ppp_passwd, isp->e9.ppp_passwd, 20);
out->ppp_passwd_valid = 1;
Modified: kos/kernel/arch/dreamcast/hardware/scif.c
===================================================================
--- kos/kernel/arch/dreamcast/hardware/scif.c 2007-11-24 05:20:47 UTC (rev 550)
+++ kos/kernel/arch/dreamcast/hardware/scif.c 2007-12-12 01:12:25 UTC (rev 551)
@@ -42,7 +42,7 @@
static int serial_baud = DEFAULT_SERIAL_BAUD,
serial_fifo = DEFAULT_SERIAL_FIFO;
-// This will get set to zero if we fail to send.
+/* This will get set to zero if we fail to send. */
static int serial_enabled = 1;
/* Set serial parameters; this is not platform independent like I want
@@ -52,7 +52,7 @@
serial_fifo = fifo;
}
-// Receive ring buffer
+/* Receive ring buffer */
#define BUFSIZE 1024
static uint8 recvbuf[BUFSIZE];
static int rb_head = 0, rb_tail = 0, rb_cnt = 0;
@@ -67,11 +67,11 @@
rb_head = (rb_head + 1) % BUFSIZE;
rb_cnt++;
- // If we're within 32 bytes of being out of space, pause for
- // the moment.
+ /* If we're within 32 bytes of being out of space, pause for
+ the moment. */
if (!rb_paused && (BUFSIZE - rb_cnt) < 32) {
rb_paused = 1;
- SCSPTR2 = 0x20; // Set CTS=0
+ SCSPTR2 = 0x20; /* Set CTS=0 */
}
}
@@ -81,7 +81,7 @@
rb_tail = (rb_tail + 1) % BUFSIZE;
rb_cnt--;
- // If we're paused and clear again, re-enabled receiving.
+ /* If we're paused and clear again, re-enabled receiving. */
if (rb_paused && (BUFSIZE - rb_cnt) >= 64) {
rb_paused = 0;
SCSPTR2 = 0x00;
@@ -104,14 +104,14 @@
out if possible. If our internal ring buffer comes close to overflowing,
the best we can do is twiddle RTS/CTS for a while. */
static void scif_err_irq(irq_t src, irq_context_t * cxt) {
- // Clear status bits
+ /* Clear status bits */
SCSCR2 &= ~0x08;
SCSCR2 |= 0x08;
printf("scif_err_irq called\n");
- // Did we get an error condition?
- if (SCFSR2 & 0x9c) { // Check ER, BRK, FER, PER
+ /* Did we get an error condition? */
+ if (SCFSR2 & 0x9c) { /* Check ER, BRK, FER, PER */
printf("SCFSR2 status was %04x\n", SCFSR2);
/* Try to clear it */
SCFCR2 = 0x06;
@@ -128,29 +128,26 @@
}
static void scif_data_irq(irq_t src, irq_context_t * cxt) {
- // Clear status bits
+ /* Clear status bits */
SCSCR2 &= ~0x40;
SCSCR2 |= 0x40;
- //printf("scif_data_irq called\n");
-
- // Check for received data available.
+ /* Check for received data available. */
if (SCFSR2 & 3) {
while (SCFDR2 & 0x1f) {
int c = SCFRDR2;
- //printf("received char '%d'\n", c);
rb_push_char(c);
}
SCFSR2 &= ~3;
}
}
-// Are we using IRQs?
+/* Are we using IRQs? */
static int scif_irq_usage = 0;
int scif_set_irq_usage(int on) {
scif_irq_usage = on;
- // Clear out the buffer in any case
+ /* Clear out the buffer in any case */
rb_reset();
if (scif_irq_usage) {
@@ -176,26 +173,26 @@
return 0;
}
-// We are always detected, though we might end up realizing there's no
-// cable connected later...
+/* We are always detected, though we might end up realizing there's no
+ cable connected later... */
int scif_detected() {
return 1;
}
-// We use this for the dbgio interface because we always init SCIF.
+/* We use this for the dbgio interface because we always init SCIF. */
int scif_init_fake() {
return 0;
}
/* Initialize the SCIF port; baud_rate must be at least 9600 and
no more than 57600. 115200 does NOT work for most PCs. */
-// recv trigger to 1 byte
+/* recv trigger to 1 byte */
int scif_init() {
int i;
/* int fifo = 1; */
- // If dcload-serial is active, then do nothing here, or we'll
- // screw that up.
+ /* If dcload-serial is active, then do nothing here, or we'll
+ screw that up. */
if (dcload_type == DCLOAD_TYPE_SER)
return 0;
@@ -209,7 +206,7 @@
SCSMR2 = 0;
/* If baudrate unset, set baudrate, N = P0/(32*B)-1 */
- // B = P0/32*(N+1)
+ /* B = P0/32*(N+1) */
if (SCBRR2 == 0xff)
SCBRR2 = (50000000 / (32 * serial_baud)) - 1;
@@ -252,7 +249,7 @@
}
if (scif_irq_usage) {
- // Do we have anything ready?
+ /* Do we have anything ready? */
if (rb_space_used() <= 0) {
errno = EAGAIN;
return -1;
@@ -266,10 +263,10 @@
return -1;
}
- // Get the input char
+ /* Get the input char */
c = SCFRDR2;
- // Ack
+ /* Ack */
SCFSR2 &= ~0x92;
return c;
@@ -366,7 +363,7 @@
return i;
}
-// Tie all of that together into a dbgio package.
+/* Tie all of that together into a dbgio package. */
dbgio_handler_t dbgio_scif = {
"scif",
scif_detected,
Modified: kos/kernel/arch/dreamcast/hardware/video.c
===================================================================
--- kos/kernel/arch/dreamcast/hardware/video.c 2007-11-24 05:20:47 UTC (rev 550)
+++ kos/kernel/arch/dreamcast/hardware/video.c 2007-12-12 01:12:25 UTC (rev 551)
@@ -11,20 +11,20 @@
#include <string.h>
#include <stdio.h>
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
CVSID("$Id: video.c,v 1.11.2.2 2003/08/02 01:52:31 bardtx Exp $");
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
-//-----------------------------------------------------------------------------
-// This table is indexed w/ DM_*
+/*-----------------------------------------------------------------------------*/
+ /* This table is indexed w/ DM_* */
vid_mode_t vid_builtin[DM_MODE_COUNT] = {
- // NULL mode..
- // DM_INVALID = 0
+ /* NULL mode.. */
+ /* DM_INVALID = 0 */
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, { 0, 0, 0, 0 } },
- // 320x240 VGA 60Hz
- // DM_320x240_VGA
+ /* 320x240 VGA 60Hz */
+ /* DM_320x240_VGA */
{
DM_320x240,
320, 240,
@@ -40,8 +40,8 @@
{ 0, 0, 0, 0 }
},
- // 320x240 NTSC 60Hz
- // DM_320x240_NTSC
+ /* 320x240 NTSC 60Hz */
+ /* DM_320x240_NTSC */
{
DM_320x240,
320, 240,
@@ -57,8 +57,8 @@
{ 0, 0, 0, 0 }
},
- // 640x480 VGA 60Hz
- // DM_640x480_VGA
+ /* 640x480 VGA 60Hz */
+ /* DM_640x480_VGA */
{
DM_640x480,
640, 480,
@@ -74,8 +74,8 @@
{ 0, 0, 0, 0 }
},
- // 640x480 NTSC 60Hz IL
- // DM_640x480_NTSC_IL
+ /* 640x480 NTSC 60Hz IL */
+ /* DM_640x480_NTSC_IL */
{
DM_640x480,
640, 480,
@@ -91,13 +91,13 @@
{ 0, 0, 0, 0 }
},
- // 800x608 NTSC 60Hz (VGA) [BROKEN!]
- // DM_800x608_VGA
+ /* 800x608 NTSC 60Hz (VGA) [BROKEN!] */
+ /* DM_800x608_VGA */
{
DM_800x608,
320, 240,
VID_INTERLACE,
- 1/*CT_ANY*/, // This will block the mode from being set.
+ 1/*CT_ANY*/, /* This will block the mode from being set. */
0,
262, 857,
164, 24,
@@ -108,8 +108,8 @@
{ 0, 0, 0, 0 }
},
- // 640x480 PAL 50Hz IL
- // DM_640x480_PAL_IL
+ /* 640x480 PAL 50Hz IL */
+ /* DM_640x480_PAL_IL */
{
DM_640x480,
640, 480,
@@ -125,8 +125,8 @@
{ 0, 0, 0, 0 }
},
- // 256x256 PAL 50Hz IL (seems to output the same w/o VID_PAL, ie. in NTSC IL mode)
- // DM_256x256_PAL_IL
+ /* 256x256 PAL 50Hz IL (seems to output the same w/o VID_PAL, ie. in NTSC IL mode) */
+ /* DM_256x256_PAL_IL */
{
DM_256x256,
256, 256,
@@ -142,8 +142,8 @@
{ 0, 0, 0, 0 }
},
- // 768x480 NTSC 60Hz IL (thanks DCGrendel)
- // DM_768x480_NTSC_IL
+ /* 768x480 NTSC 60Hz IL (thanks DCGrendel) */
+ /* DM_768x480_NTSC_IL */
{
DM_768x480,
768, 480,
@@ -159,8 +159,8 @@
{ 0, 0, 0, 0 }
},
- // 768x576 PAL 50Hz IL (DCG)
- // DM_768x576_PAL_IL
+ /* 768x576 PAL 50Hz IL (DCG) */
+ /* DM_768x576_PAL_IL */
{
DM_768x576,
768, 576,
@@ -176,8 +176,8 @@
{ 0, 0, 0, 0 }
},
- // 768x480 PAL 50Hz IL
- // DM_768x480_PAL_IL
+ /* 768x480 PAL 50Hz IL */
+ /* DM_768x480_PAL_IL */
{
DM_768x480,
768, 480,
@@ -193,8 +193,8 @@
{ 0, 0, 0, 0 }
},
- // 320x240 PAL 50Hz (thanks Marco Martins aka Mekanaizer)
- // DM_320x240_PAL
+ /* 320x240 PAL 50Hz (thanks Marco Martins aka Mekanaizer) */
+ /* DM_320x240_PAL */
{
DM_320x240,
320, 240,
@@ -210,21 +210,21 @@
{ 0, 0, 0, 0 }
},
- // END
- // DM_SENTINEL
+ /* END */
+ /* DM_SENTINEL */
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, { 0, 0, 0, 0 } }
- // DM_MODE_COUNT
+ /* DM_MODE_COUNT */
};
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
volatile uint32 *regs = (uint32*)0xA05F8000;
vid_mode_t currmode = { 0 };
vid_mode_t *vid_mode = 0;
uint16 *vram_s;
uint32 *vram_l;
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
/* Checks the attached cable type (to the A/V port). Returns
one of the following:
0 == VGA
@@ -242,34 +242,34 @@
*porta = (*porta & 0xfff0ffff) | 0x000a0000;
- // Read port8 and port9
+ /* Read port8 and port9 */
return (*((uint16*)(porta + 1)) >> 8) & 3;
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_set_mode(int dm, int pm) {
vid_mode_t mode;
int i, ct, found;
ct = vid_check_cable();
- // Check to see if we should use a direct mode index, a generic
- // mode check, or if it's just invalid.
+ /* Check to see if we should use a direct mode index, a generic
+ mode check, or if it's just invalid. */
if (dm > DM_INVALID && dm < DM_SENTINEL) {
memcpy(&mode, &vid_builtin[dm], sizeof(vid_mode_t));
} else if (dm >= DM_GENERIC_FIRST && dm <= DM_GENERIC_LAST) {
found = 0;
for (i=1; i<DM_SENTINEL; i++) {
- // Is it the right generic mode?
+ /* Is it the right generic mode? */
if (vid_builtin[i].generic != dm)
continue;
- // Do we have the right cable type?
+ /* Do we have the right cable type? */
if (vid_builtin[i].cable_type != CT_ANY &&
vid_builtin[i].cable_type != ct)
continue;
- // Ok, nothing else to check right now -- we've got our mode
+ /* Ok, nothing else to check right now -- we've got our mode */
memcpy(&mode, &vid_builtin[i], sizeof(vid_mode_t));
found = 1;
break;
@@ -283,40 +283,40 @@
return;
}
- // We set this here so actual mode is bit-depth independent..
+ /* We set this here so actual mode is bit-depth independent.. */
mode.pm = pm;
- // This is also to be generic
+ /* This is also to be generic */
mode.cable_type = ct;
- // This will make a private copy of our "mode"
+ /* This will make a private copy of our "mode" */
vid_set_mode_ex(&mode);
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_set_mode_ex(vid_mode_t *mode) {
static uint8 bpp[4] = { 2, 2, 0, 4 };
uint16 ct;
uint32 data;
- // Verify cable type for video mode.
+ /* Verify cable type for video mode. */
ct = vid_check_cable();
if (mode->cable_type != CT_ANY) {
if (mode->cable_type != ct) {
- // Maybe this should have the ability to be forced (thru param)
- // so you can set a mode with VGA params with RGB cable type?
- //ct=mode->cable_type;
+ /* Maybe this should have the ability to be forced (thru param)
+ so you can set a mode with VGA params with RGB cable type? */
+ /*ct=mode->cable_type; */
dbglog(DBG_ERROR, "vid_set_mode: Mode not allowed for this cable type (%i!=%i)\n", mode->cable_type, ct);
return;
}
}
- // Blank screen and reset display enable (looks nicer)
- regs[0x3A] |= 8; // Blank
- regs[0x11] &= ~1; // Display disable
+ /* Blank screen and reset display enable (looks nicer) */
+ regs[0x3A] |= 8; /* Blank */
+ regs[0x11] &= ~1; /* Display disable */
- // Clear interlace flag if VGA (this maybe should be in here?)
+ /* Clear interlace flag if VGA (this maybe should be in here?) */
if (ct == CT_VGA) {
mode->flags &= ~VID_INTERLACE;
if (mode->flags & VID_LINEDOUBLE)
@@ -329,7 +329,7 @@
vid_border_color(0, 0, 0);
- // Pixelformat
+ /* Pixelformat */
data = (mode->pm << 2);
if (ct == CT_VGA) {
data |= 1 << 23;
@@ -338,10 +338,10 @@
}
regs[0x11] = data;
- // Linestride
+ /* Linestride */
regs[0x13] = (mode->width * bpp[mode->pm]) / 8;
- // Display size
+ /* Display size */
data = ((mode->width * bpp[mode->pm]) / 4) - 1;
if (ct == CT_VGA || (!(mode->flags & VID_INTERLACE))) {
data |= (1 << 20) | ((mode->height - 1) << 10);
@@ -351,14 +351,14 @@
}
regs[0x17] = data;
- // vblank irq
+ /* vblank irq */
if(ct == CT_VGA) {
regs[0x33] = (mode->scanint1 << 16) | (mode->scanint2 << 1);
} else {
regs[0x33] = (mode->scanint1 << 16) | mode->scanint2;
}
- // Interlace stuff
+ /* Interlace stuff */
data = 0x100;
if (mode->flags & VID_INTERLACE) {
data |= 0x10;
@@ -370,21 +370,21 @@
}
regs[0x34] = data;
- // Border window
+ /* Border window */
regs[0x35] = (mode->borderx1 << 16) | mode->borderx2;
regs[0x37] = (mode->bordery1 << 16) | mode->bordery2;
- // Scanlines and clocks.
+ /* Scanlines and clocks. */
regs[0x36] = (mode->scanlines << 16) | mode->clocks;
- // Horizontal pixel doubling
+ /* Horizontal pixel doubling */
if (mode->flags & VID_PIXELDOUBLE) {
regs[0x3A] |= 0x100;
} else {
regs[0x3A] &= ~0x100;
}
- // Bitmap window
+ /* Bitmap window */
regs[0x3B] = mode->bitmapx;
data = mode->bitmapy;
if (mode->flags & VID_PAL) {
@@ -393,43 +393,43 @@
data = (data << 16) | mode->bitmapy;
regs[0x3C] = data;
- // Everything is ok
+ /* Everything is ok */
memcpy(&currmode, mode, sizeof(vid_mode_t));
vid_mode = &currmode;
vid_set_start(0);
- // Set cable type
+ /* Set cable type */
if (mode->cable_type & 1) {
*((vuint32*)0xa0702c00) |= 0x300;
} else {
*((vuint32*)0xa0702c00) &= ~0x300;
}
- // Re-enable the display
+ /* Re-enable the display */
regs[0x3A] &= ~8;
regs[0x11] |= 1;
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_set_start(uint32 base) {
static uint8 bpp[4] = { 2, 2, 0, 4 };
- // Set vram base of current framebuffer
+ /* Set vram base of current framebuffer */
base &= 0x007FFFFF;
regs[0x14] = base;
- // These are nice to have.
+ /* These are nice to have. */
vram_s = (uint16*)(0xA5000000|base);
vram_l = (uint32*)(0xA5000000|base);
- // Set odd-field if interlaced.
+ /* Set odd-field if interlaced. */
if (vid_mode->flags & VID_INTERLACE) {
regs[0x15] = base + (currmode.width * bpp[currmode.pm]);
}
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_flip(int fb) {
uint16 oldfb;
@@ -448,14 +448,14 @@
vid_set_start(vid_mode->fb_base[vid_mode->fb_curr]);
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_border_color(int r, int g, int b) {
regs[0x0040/4] = ((r & 0xFF) << 16) |
((g & 0xFF) << 8) |
(b & 0xFF);
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
/* Clears the screen with a given color
[This is the old KOS function by Dan.]
@@ -484,7 +484,7 @@
}
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
/* Clears all of video memory as quickly as possible
[This is the old KOS function by Dan.]
@@ -495,7 +495,7 @@
sq_clr((uint32 *)0xa5000000, 8*1024*1024);
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
/* Waits for a vertical refresh to start. This is the period between
when the scan beam reaches the bottom of the picture, and when it
starts again at the top.
@@ -512,17 +512,17 @@
;
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_init(int disp_mode, int pixel_mode) {
- // Set mode and clear vram
+ /* Set mode and clear vram */
vid_set_mode(disp_mode, pixel_mode);
vid_clear(0, 0, 0);
vid_flip(0);
}
-//-----------------------------------------------------------------------------
+/*-----------------------------------------------------------------------------*/
void vid_shutdown() {
- // Play nice with loaders, like KOS used to do.
+ /* Play nice with loaders, like KOS used to do. */
vid_init(DM_640x480, PM_RGB565);
}
Modified: kos/kernel/arch/dreamcast/include/dc/flashrom.h
===================================================================
--- kos/kernel/arch/dreamcast/include/dc/flashrom.h 2007-11-24 05:20:47 UTC (rev 550)
+++ kos/kernel/arch/dreamcast/include/dc/flashrom.h 2007-12-12 01:12:25 UTC (rev 551)
@@ -28,23 +28,23 @@
/**
An enumeration of partitions available in the flashrom. */
-#define FLASHROM_PT_SYSTEM 0 //< Factory settings (read-only, 8K)
-#define FLASHROM_PT_RESERVED 1 //< reserved (all 0s, 8K)
-#define FLASHROM_PT_BLOCK_1 2 //< Block allocated (16K)
-#define FLASHROM_PT_SETTINGS 3 //< Game settings (block allocated, 32K)
-#define FLASHROM_PT_BLOCK_2 4 //< Block allocated (64K)
+#define FLASHROM_PT_SYSTEM 0 /*< Factory settings (read-only, 8K) */
+#define FLASHROM_PT_RESERVED 1 /*< reserved (all 0s, 8K) */
+#define FLASHROM_PT_BLOCK_1 2 /*< Block allocated (16K) */
+#define FLASHROM_PT_SETTINGS 3 /*< Game settings (block allocated, 32K) */
+#define FLASHROM_PT_BLOCK_2 4 /*< Block allocated (64K) */
/**
An enumeration of logical blocks available in the flashr...
[truncated message content] |
|
From: <at...@us...> - 2008-04-04 21:44:39
|
Revision: 564
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=564&view=rev
Author: atani
Date: 2008-04-04 14:44:27 -0700 (Fri, 04 Apr 2008)
Log Message:
-----------
Adding svn:ignore for most generated files
Property Changed:
----------------
dcload/dcload-ip/example-src/
dcload/dcload-ip/host-src/tool/
dcload/dcload-ip/target-src/1st_read/
dcload/dcload-ip/target-src/dcload/
dcload/dcload-serial/example-src/
dcload/dcload-serial/host-src/misc/
dcload/dcload-serial/host-src/tool/
dcload/dcload-serial/target-src/1st_read/
dcload/dcload-serial/target-src/dcload/
kos/
kos/addons/lib/dreamcast/
kos/doc/manual/
kos/examples/dreamcast/2ndmix/
kos/kernel/arch/dreamcast/kernel/
kos/kernel/arch/dreamcast/sound/arm/
kos/kernel/exports/
kos/kernel/stubs/
kos/lib/dreamcast/
kos/utils/dc-chain/
kos/utils/gba-crcfix/
kos/utils/genromfs/
kos/utils/vqenc/
kos/utils/wav2adpcm/
kos-ports/libmp3/xingmp3/
kos-ports/liboggvorbis/liboggvorbis/libogg/build/
kos-ports/liboggvorbis/liboggvorbis/libogg/src/
kos-ports/liboggvorbis/liboggvorbis/libvorbis/build/
kos-ports/liboggvorbis/liboggvorbis/libvorbis/lib/
kos-ports/liboggvorbis/liboggvorbisplay/lib/
kos-ports/lua/lib/
Property changes on: dcload/dcload-ip/example-src
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
Property changes on: dcload/dcload-ip/host-src/tool
___________________________________________________________________
Name: svn:ignore
+ dc-tool
Property changes on: dcload/dcload-ip/target-src/1st_read
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
Property changes on: dcload/dcload-ip/target-src/dcload
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
Property changes on: dcload/dcload-serial/example-src
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
Property changes on: dcload/dcload-serial/host-src/misc
___________________________________________________________________
Name: svn:ignore
+ lzo
Property changes on: dcload/dcload-serial/host-src/tool
___________________________________________________________________
Name: svn:ignore
+ dc-tool
Property changes on: dcload/dcload-serial/target-src/1st_read
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
Property changes on: dcload/dcload-serial/target-src/dcload
___________________________________________________________________
Name: svn:ignore
+ *.bin
*.srec
*.lzo
Property changes on: kos
___________________________________________________________________
Name: svn:ignore
+ environ.sh
Property changes on: kos/addons/lib/dreamcast
___________________________________________________________________
Name: svn:ignore
+ *.a
Property changes on: kos/doc/manual
___________________________________________________________________
Name: svn:ignore
+ kos_html.zip
kos_html
kgl_html.zip
kgl_html
kos.pdf
kos.aux
kos.log
Property changes on: kos/examples/dreamcast/2ndmix
___________________________________________________________________
Name: svn:ignore
+ romdisk.img
Property changes on: kos/kernel/arch/dreamcast/kernel
___________________________________________________________________
Name: svn:ignore
+ arch_exports.c
Property changes on: kos/kernel/arch/dreamcast/sound/arm
___________________________________________________________________
Name: svn:ignore
+ prog.elf
Property changes on: kos/kernel/exports
___________________________________________________________________
Name: svn:ignore
+ kernel_exports.c
Property changes on: kos/kernel/stubs
___________________________________________________________________
Name: svn:ignore
+ *
Property changes on: kos/lib/dreamcast
___________________________________________________________________
Name: svn:ignore
+ *.a
Property changes on: kos/utils/dc-chain
___________________________________________________________________
Name: svn:ignore
+ logs
Property changes on: kos/utils/gba-crcfix
___________________________________________________________________
Name: svn:ignore
+ gba-crcfix
Property changes on: kos/utils/genromfs
___________________________________________________________________
Name: svn:ignore
+ genromfs
Property changes on: kos/utils/vqenc
___________________________________________________________________
Name: svn:ignore
+ vqenc
Property changes on: kos/utils/wav2adpcm
___________________________________________________________________
Name: svn:ignore
+ wav2adpcm
Property changes on: kos-ports/libmp3/xingmp3
___________________________________________________________________
Name: svn:ignore
+ *.a
Property changes on: kos-ports/liboggvorbis/liboggvorbis/libogg/build
___________________________________________________________________
Name: svn:ignore
+ *
Property changes on: kos-ports/liboggvorbis/liboggvorbis/libogg/src
___________________________________________________________________
Name: svn:ignore
+ *.o
*.a
Property changes on: kos-ports/liboggvorbis/liboggvorbis/libvorbis/build
___________________________________________________________________
Name: svn:ignore
+ *
Property changes on: kos-ports/liboggvorbis/liboggvorbis/libvorbis/lib
___________________________________________________________________
Name: svn:ignore
+ *
Property changes on: kos-ports/liboggvorbis/liboggvorbisplay/lib
___________________________________________________________________
Name: svn:ignore
+ *
Property changes on: kos-ports/lua/lib
___________________________________________________________________
Name: svn:ignore
+ *.a
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-05-19 15:23:47
|
Revision: 583
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=583&view=rev
Author: ljsebald
Date: 2008-05-19 08:23:23 -0700 (Mon, 19 May 2008)
Log Message:
-----------
Adding in a new synchronization primitive: reader/writer semaphores, along with an example program for them.
Modified Paths:
--------------
kos/examples/dreamcast/basic/threading/Makefile
kos/kernel/thread/Makefile
Added Paths:
-----------
kos/examples/dreamcast/basic/threading/rwsem/
kos/examples/dreamcast/basic/threading/rwsem/Makefile
kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c
kos/include/kos/rwsem.h
kos/kernel/thread/rwsem.c
Modified: kos/examples/dreamcast/basic/threading/Makefile
===================================================================
--- kos/examples/dreamcast/basic/threading/Makefile 2008-05-19 14:49:36 UTC (rev 582)
+++ kos/examples/dreamcast/basic/threading/Makefile 2008-05-19 15:23:23 UTC (rev 583)
@@ -7,11 +7,14 @@
all:
$(KOS_MAKE) -C general
+ $(KOS_MAKE) -C rwsem
clean:
$(KOS_MAKE) -C general clean
+ $(KOS_MAKE) -C rwsem clean
dist:
$(KOS_MAKE) -C general dist
+ $(KOS_MAKE) -C rwsem dist
Added: kos/examples/dreamcast/basic/threading/rwsem/Makefile
===================================================================
--- kos/examples/dreamcast/basic/threading/rwsem/Makefile (rev 0)
+++ kos/examples/dreamcast/basic/threading/rwsem/Makefile 2008-05-19 15:23:23 UTC (rev 583)
@@ -0,0 +1,29 @@
+# KallistiOS ##version##
+#
+# basic/threading/rwsem/Makefile
+# Copyright (C) 2008 Lawrence Sebald
+#
+
+all: rm-elf rwsem_test.elf
+
+include $(KOS_BASE)/Makefile.rules
+
+OBJS = rwsem_test.o
+
+clean: rm-elf
+ -rm -f $(OBJS)
+
+rm-elf:
+ -rm -f rwsem_test.elf
+
+rwsem_test.elf: $(OBJS)
+ $(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o rwsem_test.elf $(KOS_START) \
+ $(OBJS) $(DATAOBJS) $(OBJEXTRA) $(KOS_LIBS)
+
+
+run: rwsem_test.elf
+ $(KOS_LOADER) rwsem_test.elf
+
+dist:
+ rm -f $(OBJS)
+ $(KOS_STRIP) rwsem_test.elf
\ No newline at end of file
Added: kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c
===================================================================
--- kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c (rev 0)
+++ kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-19 15:23:23 UTC (rev 583)
@@ -0,0 +1,146 @@
+/* KallistiOS ##version##
+
+ rwsem_test.c
+ Copyright (C) 2008 Lawrence Sebald
+
+*/
+
+/* This program is a test of the reader/writer semaphores added in KOS 1.3.0.
+ Basically, what a reader/writer semaphore does is it allows unlimited readers
+ to occupy their critical sections, while guaranteeing exclusive access to
+ writers. This is a concept that I picked up from my undergraduate operating
+ systems class that I figured would probably be useful for KOS. */
+
+#include <stdio.h>
+
+#include <kos/thread.h>
+#include <kos/rwsem.h>
+
+#include <arch/arch.h>
+#include <dc/maple.h>
+#include <dc/maple/controller.h>
+
+#define UNUSED __attribute__((unused))
+
+rw_semaphore_t *s = NULL;
+uint32 number = 0;
+
+void writer0(void *param UNUSED) {
+ int i;
+
+ for(i = 0; i < 20; ++i) {
+ if(rwsem_write_lock(s)) {
+ printf("Writer 0 could not obtain write lock!\n");
+ return;
+ }
+
+ printf("Writer 0 obtained write lock\n");
+ number += 8;
+ rwsem_write_unlock(s);
+
+ thd_sleep(10);
+ }
+
+ printf("Writer 0 done\n");
+}
+
+void writer1(void *param UNUSED) {
+ int i;
+
+ for(i = 0; i < 17; ++i) {
+ if(rwsem_write_lock(s)) {
+ printf("Writer 1 could not obtain write lock!\n");
+ return;
+ }
+
+ printf("Writer 1 obtained write lock\n");
+ number *= 3;
+ rwsem_write_unlock(s);
+
+ thd_sleep(5);
+ }
+
+ printf("Writer 1 done\n");
+}
+
+void reader0(void *param UNUSED) {
+ int i;
+
+ for(i = 0; i < 12; ++i) {
+ if(rwsem_read_lock(s)) {
+ printf("Reader 0 could not obtain read lock!\n");
+ return;
+ }
+
+ printf("Reader 0 obtained read lock\n");
+ printf("Number: %lu\n", number);
+ rwsem_read_unlock(s);
+
+ thd_sleep(20);
+ }
+
+ printf("Reader 0 done\n");
+}
+
+void reader1(void *param UNUSED) {
+ int i;
+
+ for(i = 0; i < 23; ++i) {
+ if(rwsem_read_lock(s)) {
+ printf("Reader 1 could not obtain read lock!\n");
+ return;
+ }
+
+ printf("Reader 1 obtained read lock\n");
+ printf("Number * 2: %lu\n", number * 2);
+ rwsem_read_unlock(s);
+
+ thd_sleep(16);
+ }
+
+ printf("Reader 1 done\n");
+}
+
+KOS_INIT_FLAGS(INIT_DEFAULT);
+int main(int argc, char *argv[]) {
+ kthread_t *w0, *w1, *r0, *r1;
+
+ /* Exit if the user presse all buttons at once. */
+ cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y,
+ arch_exit);
+
+ printf("KallistiOS Reader/Writer Semaphore test program\n");
+
+ /* Create the reader/writer semaphore that will be used. */
+ s = rwsem_create();
+
+ if(!s) {
+ printf("Could not create RW semaphore, bailing out!\n");
+ arch_exit();
+ }
+
+ printf("About to create threads\n");
+ w0 = thd_create(writer0, NULL);
+ w1 = thd_create(writer1, NULL);
+ r0 = thd_create(reader0, NULL);
+ r1 = thd_create(reader1, NULL);
+
+ printf("About to sleep\n");
+ thd_wait(w0);
+ thd_wait(w1);
+ thd_wait(r0);
+ thd_wait(r1);
+
+ if(rwsem_read_lock(s)) {
+ printf("Could not obtain final read lock!\n");
+ arch_exit();
+ }
+
+ printf("Final number: %lu\n", number);
+
+ rwsem_read_unlock(s);
+ rwsem_destroy(s);
+
+ printf("Reader/Writer semaphore tests completed successfully!\n");
+ return 0;
+}
Added: kos/include/kos/rwsem.h
===================================================================
--- kos/include/kos/rwsem.h (rev 0)
+++ kos/include/kos/rwsem.h 2008-05-19 15:23:23 UTC (rev 583)
@@ -0,0 +1,86 @@
+/* KallistiOS ##version##
+
+ include/kos/rwsem.h
+ Copyright (C) 2008 Lawrence Sebald
+
+*/
+
+/* This file defines a concept that might be familiar to anyone who's ever
+ hacked around on the Linux kernel a bit: reader/writer semaphores. Basically,
+ reader/writer semaphores allow an unlimitted readers to occupy the critical
+ section at any given time. Since readers, by definition, do not change any
+ data other than their own local variables this should in theory be safe.
+ Writers on the other hand require exclusive access to the critical section.
+ Writers only may proceed into the critical section if the write lock is not
+ held on the semaphore and if there are no readers currently in the critical
+ section. Also, no reader will be allowed into the critical section if the
+ write lock is held. */
+
+#ifndef __KOS_RWSEM_H
+#define __KOS_RWSEM_H
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+
+#include <sys/queue.h>
+
+/* Reader/writer semaphore structure */
+typedef struct rw_semaphore {
+ /* List entry for the global list of reader/writer semaphores */
+ LIST_ENTRY(rw_semaphore) list;
+
+ /* How many readers currently hold the semaphore lock? */
+ int read_count;
+
+ /* Does a writer currently hold the lock? */
+ int write_lock;
+} rw_semaphore_t;
+
+LIST_HEAD(rwsemlist, rw_semaphore);
+
+/* Allocate a new reader/writer semaphore. Returns NULL on failure.
+ ENOMEM - Out of memory */
+rw_semaphore_t *rwsem_create();
+
+/* Destroy a reader/writer semaphore */
+void rwsem_destroy(rw_semaphore_t *s);
+
+/* Lock a reader/writer semaphore for reading. Returns -1 on error.
+ EPERM - called inside an interrupt
+ EINTR - was interrupted */
+int rwsem_read_lock(rw_semaphore_t *s);
+
+/* Lock a reader/writer semaphore for writing. Returns -1 on error.
+ EPERM - called inside an interrupt
+ EINTR - was interrupted */
+int rwsem_write_lock(rw_semaphore_t *s);
+
+/* Unlock a reader/writer semaphore from a read lock. Returns -1 on error. */
+int rwsem_read_unlock(rw_semaphore_t *s);
+
+/* Unlock a reader/writer semaphore from a write lock. Returns -1 on error. */
+int rwsem_write_unlock(rw_semaphore_t *s);
+
+/* Attempt to lock a reader/writer semaphore for reading. If the call to
+ rwsem_read_lock() would normally block, return -1 for error.
+ EWOULDBLOCK - would block */
+int rwsem_read_trylock(rw_semaphore_t *s);
+
+/* Attempt to lock a reader/writer semaphore for writing. If the call to
+ rwsem_write_lock() would normally block, return -1 for error.
+ EWOULDBLOCK - would block */
+int rwsem_write_trylock(rw_semaphore_t *s);
+
+/* Return the reader/writer semaphore reader count */
+int rwsem_read_count(rw_semaphore_t *s);
+
+/* Return the reader/writer semaphore write lock status */
+int rwsem_write_locked(rw_semaphore_t *s);
+
+/* Init / shutdown */
+int rwsem_init();
+void rwsem_shutdown();
+
+__END_DECLS
+
+#endif /* __KOS_RWSEM_H */
Modified: kos/kernel/thread/Makefile
===================================================================
--- kos/kernel/thread/Makefile 2008-05-19 14:49:36 UTC (rev 582)
+++ kos/kernel/thread/Makefile 2008-05-19 15:23:23 UTC (rev 583)
@@ -6,7 +6,7 @@
# $Id: Makefile,v 1.4 2003/02/14 08:25:07 bardtx Exp $
OBJS = sem.o cond.o mutex.o genwait.o
-OBJS += thread.o
+OBJS += thread.o rwsem.o
SUBDIRS =
include $(KOS_BASE)/Makefile.prefab
Added: kos/kernel/thread/rwsem.c
===================================================================
--- kos/kernel/thread/rwsem.c (rev 0)
+++ kos/kernel/thread/rwsem.c 2008-05-19 15:23:23 UTC (rev 583)
@@ -0,0 +1,224 @@
+/* KallistiOS ##version##
+
+ rwsem.c
+ Copyright (C) 2008 Lawrence Sebald
+*/
+
+/* Defines reader/writer semaphores */
+
+#include <malloc.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <kos/rwsem.h>
+#include <kos/genwait.h>
+#include <arch/spinlock.h>
+
+/* Reader/writer semaphore list spinlock */
+static spinlock_t mutex;
+
+/* Global list of reader/writer semaphores */
+static struct rwsemlist rwsem_list;
+
+/* Allocate a new reader/writer semaphore */
+rw_semaphore_t *rwsem_create() {
+ rw_semaphore_t *s;
+
+ s = (rw_semaphore_t *)malloc(sizeof(rw_semaphore_t));
+ if(!s) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ s->read_count = 0;
+ s->write_lock = 0;
+
+ spinlock_lock(&mutex);
+ LIST_INSERT_HEAD(&rwsem_list, s, list);
+ spinlock_unlock(&mutex);
+
+ return s;
+}
+
+/* Destroy a reader/writer semaphore */
+void rwsem_destroy(rw_semaphore_t *s) {
+ /* XXXX: Should really cause anyone waiting to get an error back on their
+ wait... hmm. */
+ spinlock_lock(&mutex);
+ LIST_REMOVE(s, list);
+ spinlock_unlock(&mutex);
+
+ free(s);
+}
+
+/* Lock a reader/writer semaphore for reading */
+int rwsem_read_lock(rw_semaphore_t *s) {
+ int old, rv = 0;
+
+ if(irq_inside_int()) {
+ dbglog(DBG_WARNING, "rwsem_read_lock: called inside interrupt\n");
+ errno = EPERM;
+ return -1;
+ }
+
+ old = irq_disable();
+
+ /* If the write lock is not held, let the thread proceed */
+ if(!s->write_lock) {
+ ++s->read_count;
+ }
+ else {
+ /* Block until the write lock is not held any more */
+ rv = genwait_wait(s, "rwsem_read_lock", 0, NULL);
+
+ if(rv < 0) {
+ assert(errno == EINTR);
+ rv = -1;
+ }
+ else {
+ ++s->read_count;
+ }
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Lock a reader/writer semaphore for writing */
+int rwsem_write_lock(rw_semaphore_t *s) {
+ int old, rv = 0;
+
+ if(irq_inside_int()) {
+ dbglog(DBG_WARNING, "rwsem_write_lock: called inside interrupt\n");
+ errno = EPERM;
+ return -1;
+ }
+
+ old = irq_disable();
+
+ /* If the write lock is not held and there are no readers in their critical
+ sections, let the thread proceed. */
+ if(!s->write_lock && !s->read_count) {
+ s->write_lock = 1;
+ }
+ else {
+ /* Block until the write lock is not held and there are no readers
+ inside their critical sections */
+ rv = genwait_wait(&s->write_lock, "rwsem_write_lock", 0, NULL);
+
+ if(rv < 0) {
+ assert(errno == EINTR);
+ rv = -1;
+ }
+ else {
+ s->write_lock = 1;
+ }
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Unlock a reader/writer semaphore from a read lock. */
+int rwsem_read_unlock(rw_semaphore_t *s) {
+ int old;
+
+ old = irq_disable();
+
+ --s->read_count;
+
+ /* If this was the last reader, attempt to wake any writers waiting. */
+ if(!s->read_count) {
+ genwait_wake_one(&s->write_lock);
+ }
+
+ irq_restore(old);
+
+ return 0;
+}
+
+/* Unlock a reader/writer semaphore from a write lock. */
+int rwsem_write_unlock(rw_semaphore_t *s) {
+ int old, woken;
+
+ old = irq_disable();
+
+ s->write_lock = 0;
+
+ /* Give writers priority, attempt to wake any writers first. */
+ woken = genwait_wake_cnt(&s->write_lock, 1);
+
+ if(!woken) {
+ /* No writers were waiting, wake up any readers. */
+ genwait_wake_all(s);
+ }
+
+ irq_restore(old);
+
+ return 0;
+}
+
+/* Attempt to lock a reader/writer semaphore for reading, but do not block. */
+int rwsem_read_trylock(rw_semaphore_t *s) {
+ int old, rv;
+
+ old = irq_disable();
+
+ /* Is the write lock held? */
+ if(s->write_lock) {
+ rv = -1;
+ errno = EWOULDBLOCK;
+ }
+ else {
+ rv = 0;
+ ++s->read_count;
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Attempt to lock a reader/writer semaphore for writing, but do not block. */
+int rwsem_write_trylock(rw_semaphore_t *s) {
+ int old, rv;
+
+ old = irq_disable();
+
+ /* Are there any readers in their critical sections, or is the write lock
+ already held, if so we can't do anything about that now. */
+ if(s->read_count || s->write_lock) {
+ rv = -1;
+ errno = EWOULDBLOCK;
+ }
+ else {
+ rv = 0;
+ s->write_lock = 1;
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Return the current reader count */
+int rwsem_read_count(rw_semaphore_t *s) {
+ return s->read_count;
+}
+
+/* Return the current status of the write lock */
+int rwsem_write_locked(rw_semaphore_t *s) {
+ return s->write_lock;
+}
+
+/* Initialize reader/writer semaphores */
+int rwsem_init() {
+ LIST_INIT(&rwsem_list);
+ spinlock_init(&mutex);
+ return 0;
+}
+
+/* Shut down reader/writer semaphores */
+void rwsem_shutdown() {
+ /* XXXX: Do something useful */
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-05-19 15:28:49
|
Revision: 584
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=584&view=rev
Author: ljsebald
Date: 2008-05-19 08:28:34 -0700 (Mon, 19 May 2008)
Log Message:
-----------
Oops... forgot a few things.
Modified Paths:
--------------
kos/include/kos.h
kos/kernel/thread/thread.c
Modified: kos/include/kos.h
===================================================================
--- kos/include/kos.h 2008-05-19 15:23:23 UTC (rev 583)
+++ kos/include/kos.h 2008-05-19 15:28:34 UTC (rev 584)
@@ -29,6 +29,7 @@
#include <kos/limits.h>
#include <kos/thread.h>
#include <kos/sem.h>
+#include <kos/rwsem.h>
#include <kos/mutex.h>
#include <kos/cond.h>
#include <kos/genwait.h>
Modified: kos/kernel/thread/thread.c
===================================================================
--- kos/kernel/thread/thread.c 2008-05-19 15:23:23 UTC (rev 583)
+++ kos/kernel/thread/thread.c 2008-05-19 15:28:34 UTC (rev 584)
@@ -12,6 +12,7 @@
#include <reent.h>
#include <kos/thread.h>
#include <kos/sem.h>
+#include <kos/rwsem.h>
#include <kos/cond.h>
#include <kos/genwait.h>
#include <arch/irq.h>
@@ -769,6 +770,7 @@
/* Initialize thread sync primitives */
genwait_init();
+ rwsem_init();
sem_init();
cond_init();
@@ -809,6 +811,7 @@
}
/* Shutdown thread sync primitives */
+ rwsem_shutdown();
sem_shutdown();
cond_shutdown();
genwait_shutdown();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-05-20 03:05:51
|
Revision: 588
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=588&view=rev
Author: ljsebald
Date: 2008-05-19 20:05:38 -0700 (Mon, 19 May 2008)
Log Message:
-----------
Add support for "upgrading" a reader/writer semaphore from a read lock to a write lock.
Modified Paths:
--------------
kos/include/kos/rwsem.h
kos/kernel/thread/rwsem.c
Modified: kos/include/kos/rwsem.h
===================================================================
--- kos/include/kos/rwsem.h 2008-05-20 02:45:34 UTC (rev 587)
+++ kos/include/kos/rwsem.h 2008-05-20 03:05:38 UTC (rev 588)
@@ -71,6 +71,17 @@
EWOULDBLOCK - would block */
int rwsem_write_trylock(rw_semaphore_t *s);
+/* "Upgrade" a read lock to a write lock. Returns -1 on error.
+ EPERM - called inside an interrupt
+ EINTR - was interrupted */
+int rwsem_read_upgrade(rw_semaphore_t *s);
+
+/* Attempt to upgrade a read lock to a write lock. If the call to
+ rwsem_read_upgrade() would normally block, return -1 for error.
+ Note that on error, the read lock is still held.
+ EWOULDBLOCK - would block */
+int rwsem_read_tryupgrade(rw_semaphore_t *s);
+
/* Return the reader/writer semaphore reader count */
int rwsem_read_count(rw_semaphore_t *s);
Modified: kos/kernel/thread/rwsem.c
===================================================================
--- kos/kernel/thread/rwsem.c 2008-05-20 02:45:34 UTC (rev 587)
+++ kos/kernel/thread/rwsem.c 2008-05-20 03:05:38 UTC (rev 588)
@@ -201,6 +201,60 @@
return rv;
}
+/* "Upgrade" a read lock to a write lock. */
+int rwsem_read_upgrade(rw_semaphore_t *s) {
+ int old, rv = 0;
+
+ if(irq_inside_int()) {
+ dbglog(DBG_WARNING, "rwsem_read_upgrade: called inside interrupt\n");
+ errno = EPERM;
+ return -1;
+ }
+
+ old = irq_disable();
+
+ --s->read_count;
+
+ /* If there are still other readers, wait patiently for our turn. */
+ if(s->read_count) {
+ rv = genwait_wait(&s->write_lock, "rwsem_read_upgrade", 0, NULL);
+
+ if(rv < 0) {
+ assert(errno == EINTR);
+ rv = -1;
+ }
+ else {
+ s->write_lock = 1;
+ }
+ }
+ else {
+ s->write_lock = 1;
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Attempt to upgrade a read lock to a write lock, but do not block. */
+int rwsem_read_tryupgrade(rw_semaphore_t *s) {
+ int old, rv;
+
+ old = irq_disable();
+
+ if(s->read_count != 1) {
+ rv = -1;
+ errno = EWOULDBLOCK;
+ }
+ else {
+ rv = 0;
+ s->read_count = 0;
+ s->write_lock = 1;
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
/* Return the current reader count */
int rwsem_read_count(rw_semaphore_t *s) {
return s->read_count;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ljs...@us...> - 2008-05-28 13:34:32
|
Revision: 592
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=592&view=rev
Author: ljsebald
Date: 2008-05-28 06:34:29 -0700 (Wed, 28 May 2008)
Log Message:
-----------
Adding in another new synchronization primitive: recursive locks, along with an example/test program for them.
Modified Paths:
--------------
kos/examples/dreamcast/basic/threading/Makefile
kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c
kos/include/kos.h
kos/kernel/thread/Makefile
kos/kernel/thread/thread.c
Added Paths:
-----------
kos/examples/dreamcast/basic/threading/recursive_lock/
kos/examples/dreamcast/basic/threading/recursive_lock/Makefile
kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c
kos/include/kos/recursive_lock.h
kos/kernel/thread/recursive_lock.c
Modified: kos/examples/dreamcast/basic/threading/Makefile
===================================================================
--- kos/examples/dreamcast/basic/threading/Makefile 2008-05-21 22:04:23 UTC (rev 591)
+++ kos/examples/dreamcast/basic/threading/Makefile 2008-05-28 13:34:29 UTC (rev 592)
@@ -8,13 +8,15 @@
all:
$(KOS_MAKE) -C general
$(KOS_MAKE) -C rwsem
+ $(KOS_MAKE) -C recursive_lock
clean:
$(KOS_MAKE) -C general clean
$(KOS_MAKE) -C rwsem clean
-
+ $(KOS_MAKE) -C recursive_lock clean
+
dist:
$(KOS_MAKE) -C general dist
$(KOS_MAKE) -C rwsem dist
+ $(KOS_MAKE) -C recursive_lock dist
-
Added: kos/examples/dreamcast/basic/threading/recursive_lock/Makefile
===================================================================
--- kos/examples/dreamcast/basic/threading/recursive_lock/Makefile (rev 0)
+++ kos/examples/dreamcast/basic/threading/recursive_lock/Makefile 2008-05-28 13:34:29 UTC (rev 592)
@@ -0,0 +1,29 @@
+# KallistiOS ##version##
+#
+# basic/threading/recursive_lock/Makefile
+# Copyright (C) 2008 Lawrence Sebald
+#
+
+all: rm-elf rlock_test.elf
+
+include $(KOS_BASE)/Makefile.rules
+
+OBJS = rlock_test.o
+
+clean: rm-elf
+ -rm -f $(OBJS)
+
+rm-elf:
+ -rm -f rlock_test.elf
+
+rlock_test.elf: $(OBJS)
+ $(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o rlock_test.elf $(KOS_START) \
+ $(OBJS) $(DATAOBJS) $(OBJEXTRA) $(KOS_LIBS)
+
+
+run: rlock_test.elf
+ $(KOS_LOADER) rlock_test.elf
+
+dist:
+ rm -f $(OBJS)
+ $(KOS_STRIP) rlock_test.elf
\ No newline at end of file
Added: kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c
===================================================================
--- kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c (rev 0)
+++ kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c 2008-05-28 13:34:29 UTC (rev 592)
@@ -0,0 +1,128 @@
+/* KallistiOS ##version##
+
+ rlock_test.c
+ Copyright (C) 2008 Lawrence Sebald
+
+*/
+
+/* This program is a test for the recursive locks added in KOS 1.3.0. This
+ synchronization primitive works essentially the same as a mutex, but allows
+ the thread that owns the lock to acquire it as many times as it wants. */
+
+#include <stdio.h>
+
+#include <kos/thread.h>
+#include <kos/recursive_lock.h>
+
+#include <arch/arch.h>
+#include <dc/maple.h>
+#include <dc/maple/controller.h>
+
+#define UNUSED __attribute__((unused))
+
+recursive_lock_t *l = NULL;
+
+void thd0(void *param UNUSED) {
+ int i;
+
+ printf("Thd 0: About to obtain lock 10 times\n");
+
+ for(i = 0; i < 10; ++i) {
+ rlock_lock(l);
+ }
+
+ printf("Thd 0: Lock acquired %d times\n", l->count);
+ printf("Thd 0: About to sleep\n");
+ thd_sleep(100);
+
+ printf("Thd 0: Awake, about to release lock 9 times\n");
+
+ for(i = 0; i < 9; ++i) {
+ rlock_unlock(l);
+ }
+
+ printf("Thd 0: About to sleep again\n");
+ thd_sleep(10);
+
+ printf("Thd 0: Awake, about to release lock\n");
+ rlock_unlock(l);
+ printf("Thd 0: done\n");
+}
+
+void thd1(void *param UNUSED) {
+ printf("Thd 1: About to obtain lock 2 times\n");
+ rlock_lock(l);
+ rlock_lock(l);
+
+ printf("Thd 1: About to pass timeslice\n");
+ thd_pass();
+
+ printf("Thd 1: Awake, going to release lock 2 times\n");
+ rlock_unlock(l);
+ rlock_unlock(l);
+
+ printf("Thd 1: About to obtain lock 1 time\n");
+ rlock_lock(l);
+
+ printf("Thd 1: About to release lock\n");
+ rlock_unlock(l);
+ printf("Thd 1: done\n");
+}
+
+void thd2(void *param UNUSED) {
+ int i;
+
+ printf("Thd 2: About to obtain lock 200 times\n");
+
+ for(i = 0; i < 200; ++i) {
+ rlock_lock(l);
+ }
+
+ printf("Thd 2: About to release lock 200 times\n");
+
+ for(i = 0; i < 200; ++i) {
+ rlock_unlock(l);
+ }
+
+ printf("Thd 2: done\n");
+}
+
+KOS_INIT_FLAGS(INIT_DEFAULT);
+
+int main(int argc, char *argv[]) {
+ kthread_t *t0, *t1, *t2;
+
+ /* Exit if the user presses all buttons at once. */
+ cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y,
+ arch_exit);
+
+ printf("KallistiOS Recursive Lock test program\n");
+
+ /* Create the recursive lock */
+ l = rlock_create();
+
+ if(!l) {
+ printf("Could not create recursive lock, bailing out!\n");
+ arch_exit();
+ }
+
+ printf("About to create threads\n");
+ t0 = thd_create(thd0, NULL);
+ t1 = thd_create(thd1, NULL);
+ t2 = thd_create(thd2, NULL);
+
+ printf("About to sleep\n");
+ thd_wait(t0);
+ thd_wait(t1);
+ thd_wait(t2);
+
+ if(rlock_is_locked(l)) {
+ printf("Lock is still locked!\n");
+ arch_exit();
+ }
+
+ rlock_destroy(l);
+
+ printf("Recursive lock tests completed successfully!\n");
+ return 0;
+}
Modified: kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c
===================================================================
--- kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-21 22:04:23 UTC (rev 591)
+++ kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-28 13:34:29 UTC (rev 592)
@@ -105,7 +105,7 @@
int main(int argc, char *argv[]) {
kthread_t *w0, *w1, *r0, *r1;
- /* Exit if the user presse all buttons at once. */
+ /* Exit if the user presses all buttons at once. */
cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y,
arch_exit);
Added: kos/include/kos/recursive_lock.h
===================================================================
--- kos/include/kos/recursive_lock.h (rev 0)
+++ kos/include/kos/recursive_lock.h 2008-05-28 13:34:29 UTC (rev 592)
@@ -0,0 +1,59 @@
+/* KallistiOS ##version##
+
+ include/kos/recursive_lock.h
+ Copyright (C) 2008 Lawrence Sebald
+
+*/
+
+/* This file defines a recursive lock mechanism. Basically, think of these as
+ a mutex that a single thread can acquire as many times as it wants, but no
+ other threads can acquire. */
+
+#ifndef __KOS_RECURSIVE_LOCK_H
+#define __KOS_RECURSIVE_LOCK_H
+
+#include <sys/cdefs.h>
+__BEGIN_DECLS
+
+#include <sys/queue.h>
+#include <kos/thread.h>
+
+typedef struct recursive_lock {
+ /* What thread currently holds the lock, if any? */
+ kthread_t *holder;
+
+ /* How many times does this thread hold the lock? */
+ int count;
+} recursive_lock_t;
+
+/* Allocate a new recursive lock. Returns NULL on failure.
+ ENOMEM - Out of memory */
+recursive_lock_t *rlock_create();
+
+/* Destroy a recursive lock */
+void rlock_destroy(recursive_lock_t *l);
+
+/* Lock a recursive lock. Returns -1 on error.
+ EPERM - called inside an interrupt
+ EINTR - was interrupted */
+int rlock_lock(recursive_lock_t *l);
+
+/* Unlock a recursive lock. Returns -1 on error.
+ EPERM - the lock is not held by the current thread */
+int rlock_unlock(recursive_lock_t *l);
+
+/* Attempt to lock a recursive lock. If the call to rlock_lock() would normally
+ block, return -1 for error.
+ EWOULDBLOCK - would block */
+int rlock_trylock(recursive_lock_t *l);
+
+/* Return whether the lock is currently held. */
+int rlock_is_locked(recursive_lock_t *l);
+
+/* Init / shutdown */
+int rlock_init();
+void rlock_shutdown();
+
+__END_DECLS
+
+#endif /* !__KOS_RECURSIVE_LOCK_H */
Modified: kos/include/kos.h
===================================================================
--- kos/include/kos.h 2008-05-21 22:04:23 UTC (rev 591)
+++ kos/include/kos.h 2008-05-28 13:34:29 UTC (rev 592)
@@ -30,6 +30,7 @@
#include <kos/thread.h>
#include <kos/sem.h>
#include <kos/rwsem.h>
+#include <kos/recursive_lock.h>
#include <kos/mutex.h>
#include <kos/cond.h>
#include <kos/genwait.h>
Modified: kos/kernel/thread/Makefile
===================================================================
--- kos/kernel/thread/Makefile 2008-05-21 22:04:23 UTC (rev 591)
+++ kos/kernel/thread/Makefile 2008-05-28 13:34:29 UTC (rev 592)
@@ -6,7 +6,7 @@
# $Id: Makefile,v 1.4 2003/02/14 08:25:07 bardtx Exp $
OBJS = sem.o cond.o mutex.o genwait.o
-OBJS += thread.o rwsem.o
+OBJS += thread.o rwsem.o recursive_lock.o
SUBDIRS =
include $(KOS_BASE)/Makefile.prefab
Added: kos/kernel/thread/recursive_lock.c
===================================================================
--- kos/kernel/thread/recursive_lock.c (rev 0)
+++ kos/kernel/thread/recursive_lock.c 2008-05-28 13:34:29 UTC (rev 592)
@@ -0,0 +1,146 @@
+/* KallistiOS ##version##
+
+ recursive_lock.c
+ Copyright (C) 2008 Lawrence Sebald
+*/
+
+/* This file defines recursive locks. */
+
+#include <malloc.h>
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/queue.h>
+
+#include <kos/recursive_lock.h>
+#include <kos/thread.h>
+#include <kos/genwait.h>
+
+/* Create a recursive lock */
+recursive_lock_t *rlock_create() {
+ recursive_lock_t *rv;
+
+ rv = (recursive_lock_t *)malloc(sizeof(recursive_lock_t));
+ if(!rv) {
+ errno = ENOMEM;
+ }
+
+ rv->holder = NULL;
+ rv->count = 0;
+
+ return rv;
+}
+
+/* Destroy a recursive lock */
+void rlock_destroy(recursive_lock_t *l) {
+ assert(l);
+ assert(!l->count);
+
+ free(l);
+}
+
+/* Lock a recursive lock */
+int rlock_lock(recursive_lock_t *l) {
+ int old, rv = 0;
+
+ if(irq_inside_int()) {
+ dbglog(DBG_WARNING, "rlock_lock: called inside interrupt\n");
+ errno = EPERM;
+ return -1;
+ }
+
+ old = irq_disable();
+
+ /* If the lock is not held, let the thread proceed */
+ if(!l->count) {
+ assert(!l->holder);
+
+ l->count = 1;
+ l->holder = thd_current;
+ }
+ else if(l->holder == thd_current) {
+ ++l->count;
+ }
+ else {
+ /* Block until the lock isn't held any more */
+ rv = genwait_wait(l, "rlock_lock", 0, NULL);
+
+ if(rv < 0) {
+ assert(errno == EINTR);
+ rv = -1;
+ }
+ else {
+ l->count = 1;
+ l->holder = thd_current;
+ }
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Unlock a recursive lock */
+int rlock_unlock(recursive_lock_t *l) {
+ int old, rv = 0;
+
+ old = irq_disable();
+
+ /* Make sure we currently hold the lock */
+ if(l->holder != thd_current) {
+ rv = -1;
+ errno = EPERM;
+ }
+ else {
+ --l->count;
+
+ /* If we're done holding the lock, mark it as such, and signal the next
+ thread waiting, if any. */
+ if(!l->count) {
+ l->holder = NULL;
+ genwait_wake_one(l);
+ }
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Attempt to lock a recursive lock */
+int rlock_trylock(recursive_lock_t *l) {
+ int old, rv = 0;
+
+ old = irq_disable();
+
+ /* Check if the lock is held, if so, check if the current thread holds the
+ lock. */
+ if(l->count) {
+ if(l->holder == thd_current) {
+ ++l->count;
+ }
+ else {
+ rv = -1;
+ errno = EWOULDBLOCK;
+ }
+ }
+ else {
+ l->holder = thd_current;
+ l->count = 1;
+ }
+
+ irq_restore(old);
+ return rv;
+}
+
+/* Return whether or not the lock is currently held */
+int rlock_is_locked(recursive_lock_t *l) {
+ return !!l->count;
+}
+
+/* Initialize recursive locks */
+int rlock_init() {
+ return 0;
+}
+
+/* Shut down recursive locks */
+void rlock_shutdown() {
+}
Modified: kos/kernel/thread/thread.c
===================================================================
--- kos/kernel/thread/thread.c 2008-05-21 22:04:23 UTC (rev 591)
+++ kos/kernel/thread/thread.c 2008-05-28 13:34:29 UTC (rev 592)
@@ -13,6 +13,7 @@
#include <kos/thread.h>
#include <kos/sem.h>
#include <kos/rwsem.h>
+#include <kos/recursive_lock.h>
#include <kos/cond.h>
#include <kos/genwait.h>
#include <arch/irq.h>
@@ -771,6 +772,7 @@
/* Initialize thread sync primitives */
genwait_init();
rwsem_init();
+ rlock_init();
sem_init();
cond_init();
@@ -812,6 +814,7 @@
/* Shutdown thread sync primitives */
rwsem_shutdown();
+ rlock_shutdown();
sem_shutdown();
cond_shutdown();
genwait_shutdown();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <los...@us...> - 2008-05-30 17:32:42
|
Revision: 595
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=595&view=rev
Author: lostgeneration
Date: 2008-05-30 10:32:39 -0700 (Fri, 30 May 2008)
Log Message:
-----------
Moved check for free(NULL) up in code to avoid potential problems.
* It seems that calling free(NULL) was causing problems. Moving the check for
NULL up seems to help.
Modified Paths:
--------------
kos/doc/CHANGELOG
kos/kernel/libc/koslib/malloc.c
Modified: kos/doc/CHANGELOG
===================================================================
--- kos/doc/CHANGELOG 2008-05-28 13:43:26 UTC (rev 594)
+++ kos/doc/CHANGELOG 2008-05-30 17:32:39 UTC (rev 595)
@@ -154,6 +154,7 @@
- *** Added support for upgrading a read lock on a reader/writer semaphore to
a write lock [LS]
- *** Added a recursive lock synchronization primitive [LS]
+- *** Moved checking for free(NULL) up in code to avoid potential problems [HL]
KallistiOS version 1.2.0 -----------------------------------------------
- DC Fix to use DCARM7_CFLAGS when compiling ARM driver [Christian Groessler == CG]
Modified: kos/kernel/libc/koslib/malloc.c
===================================================================
--- kos/kernel/libc/koslib/malloc.c 2008-05-28 13:43:26 UTC (rev 594)
+++ kos/kernel/libc/koslib/malloc.c 2008-05-30 17:32:39 UTC (rev 595)
@@ -1733,6 +1733,10 @@
int dmg = 0;
#endif
+ /* standard C says if block is NULL, do not try to free it */
+ if(m == NULL)
+ return;
+
if (MALLOC_PREACTION != 0) {
return;
}
@@ -1744,9 +1748,6 @@
thd_current->tid, rv, (uint32)m);
#endif
- if (m == NULL)
- return;
-
ctl = get_memctl(m);
if (ctl->magic != BLOCK_MAGIC) {
#ifndef KM_DBG_VERBOSE
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <los...@us...> - 2008-06-20 02:40:30
|
Revision: 596
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=596&view=rev
Author: lostgeneration
Date: 2008-06-19 19:40:29 -0700 (Thu, 19 Jun 2008)
Log Message:
-----------
Removed legacy libc and libm.
* Since libc and libm are now provided by newlib on the primary port
* (Dreamcast), these are no longer used or needed.
Removed Paths:
-------------
kos/libc/
kos/libm/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <sa...@us...> - 2008-06-23 22:00:04
|
Revision: 597
http://cadcdev.svn.sourceforge.net/cadcdev/?rev=597&view=rev
Author: sannyx
Date: 2008-06-23 14:59:58 -0700 (Mon, 23 Jun 2008)
Log Message:
-----------
don't allow opening a file with O_DIR
Modified Paths:
--------------
kos/doc/CHANGELOG
kos/kernel/arch/dreamcast/sound/arm/stream.drv
kos/kernel/fs/fs_ramdisk.c
Modified: kos/doc/CHANGELOG
===================================================================
--- kos/doc/CHANGELOG 2008-06-20 02:40:29 UTC (rev 596)
+++ kos/doc/CHANGELOG 2008-06-23 21:59:58 UTC (rev 597)
@@ -155,6 +155,7 @@
a write lock [LS]
- *** Added a recursive lock synchronization primitive [LS]
- *** Moved checking for free(NULL) up in code to avoid potential problems [HL]
+- DC fs_ramdisk.c: Don't allow opening a file with O_DIR [CG]
KallistiOS version 1.2.0 -----------------------------------------------
- DC Fix to use DCARM7_CFLAGS when compiling ARM driver [Christian Groessler == CG]
Modified: kos/kernel/arch/dreamcast/sound/arm/stream.drv
===================================================================
(Binary files differ)
Modified: kos/kernel/fs/fs_ramdisk.c
===================================================================
--- kos/kernel/fs/fs_ramdisk.c 2008-06-20 02:40:29 UTC (rev 596)
+++ kos/kernel/fs/fs_ramdisk.c 2008-06-23 21:59:58 UTC (rev 597)
@@ -138,7 +138,7 @@
in the dir. */
if (fn[0] != 0) {
f = ramdisk_find(parent, fn, strlen(fn));
- if (!dir && f->type == STAT_TYPE_DIR)
+ if ((!dir && f->type == STAT_TYPE_DIR) || (dir && f->type != STAT_TYPE_DIR))
return NULL;
} else {
/* We must have been looking for the dir itself */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|